Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- **A leaked `serve.token` is rotated on Windows, not just Unix.** After SBS-953, a world-readable token was replaced on Unix, but Windows still tightened the DACL and reused the same secret. The ACL is now inspected before tightening; if anyone other than the current user, SYSTEM, or Administrators can read the file, the token is replaced. Closes SBS-1043.

### Fixed
- **Frontend tests now catch accessibility regressions automatically.** A shared axe assertion checks representative quota cards, mini charts, and update banners in the existing Frontend CI job. Color contrast remains outside jsdom coverage because it requires a rendered browser. Fixes #222.
- **`usage --all-accounts` now fetches every configured Codex and Claude account.** Account fetches run with bounded concurrency, preserve configured order, and report failures independently. Text and JSON identify each configured account while the default output remains unchanged. Fixes #274.
- **The detached Settings window now reopens where you left it.** Its saved size and position are restored and clamped on screen instead of being overwritten by a second frontend resize on every open. Closes #275.
- **`serve --refresh-interval` now controls response caching.** Successful usage and cost responses are cached separately by provider selection for the requested TTL. A zero interval disables caching, and provider failures are retried on the next request. Fixes #273.
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop-tauri/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"jsdom": "25.0.1",
"typescript": "5.6.3",
"vite": "6.4.3",
"vitest": "3.2.6"
"vitest": "3.2.6",
"vitest-axe": "^0.1.0"
}
}
35 changes: 35 additions & 0 deletions apps/desktop-tauri/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions apps/desktop-tauri/src/components/MiniBarChart.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { SimpleBarChart, StackedBarChart } from "./MiniBarChart";
import { expectNoAccessibilityViolations } from "../test/accessibility";

vi.mock("../hooks/useLocale", () => ({
useLocale: () => ({ t: () => "No data" }),
Expand All @@ -18,4 +19,18 @@ describe("MiniBarChart empty state", () => {

expect(screen.getByRole("img", { name: "No data" })).toBeTruthy();
});

it("has no detectable accessibility violations", async () => {
const { container } = render(
<SimpleBarChart
label="Daily cost"
points={[
{ date: "2026-08-18", value: 3 },
{ date: "2026-08-19", value: 5 },
]}
/>,
);

await expectNoAccessibilityViolations(container);
});
});
14 changes: 14 additions & 0 deletions apps/desktop-tauri/src/components/PlanStatusCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import PlanStatusCard from "./PlanStatusCard";
import type { ProviderUsageSnapshot, RateWindowSnapshot } from "../types/bridge";
import { expectNoAccessibilityViolations } from "../test/accessibility";

vi.mock("../hooks/useLocale", () => ({
useLocale: () => ({
Expand Down Expand Up @@ -67,6 +68,19 @@ function provider(
}

describe("PlanStatusCard", () => {
it("has no detectable accessibility violations", async () => {
const { container } = render(
<PlanStatusCard
provider={provider()}
resetTimeRelative
showAsUsed
onSelect={vi.fn()}
/>,
);

await expectNoAccessibilityViolations(container);
});

it("includes displayed quota windows in the card button name", () => {
render(
<PlanStatusCard
Expand Down
9 changes: 9 additions & 0 deletions apps/desktop-tauri/src/components/UpdateBanner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import type { UpdateStatePayload } from "../types/bridge";
import UpdateBanner from "./UpdateBanner";
import { expectNoAccessibilityViolations } from "../test/accessibility";

vi.mock("../hooks/useLocale", () => ({
useLocale: () => ({ t: (key: string) => key }),
Expand Down Expand Up @@ -81,4 +82,12 @@ describe("UpdateBanner accessibility", () => {
);
expect(screen.getByRole("alert").textContent).toContain("network failed");
});

it("has no detectable accessibility violations", async () => {
const { container } = render(
<UpdateBanner updateState={state("available")} {...handlers} />,
);

await expectNoAccessibilityViolations(container);
});
});
17 changes: 17 additions & 0 deletions apps/desktop-tauri/src/test/accessibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { axe } from "vitest-axe";
import type { AxeMatchers } from "vitest-axe";
import { expect } from "vitest";

export async function expectNoAccessibilityViolations(
container: Element,
): Promise<void> {
const results = await axe(container, {
rules: {
// jsdom does not implement the canvas API axe uses for contrast.
"color-contrast": { enabled: false },
},
});
(
expect(results) as unknown as ReturnType<typeof expect> & AxeMatchers
).toHaveNoViolations();
}
5 changes: 5 additions & 0 deletions apps/desktop-tauri/src/test/setup.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
import "@testing-library/jest-dom/vitest";
import "vitest-axe/extend-expect";
import * as axeMatchers from "vitest-axe/matchers";
import { expect } from "vitest";

expect.extend(axeMatchers);
Loading