diff --git a/.Jules/palette.md b/.Jules/palette.md index 5c1c16989..354340528 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -37,3 +37,6 @@ ## 2026-07-02 - Inline clear buttons preserve focus **Learning:** Inline clear buttons often unmount immediately after clearing state, which can drop keyboard focus to the document body. **Action:** Move focus back to the owning input before clearing state, and cover the behavior with a DOM focus test. +## 2026-08-04 - Accessible disabled buttons in test suites +**Learning:** When testing accessible disabled buttons that use `aria-disabled="true"`, Jest-DOM's `.toBeDisabled()` will fail because it strictly checks for the native HTML `disabled` attribute. +**Action:** Instead, query the button (e.g., `screen.getByRole("button", { name: ... })`) and use `.toHaveAttribute("aria-disabled", "true")` to assert its state. diff --git a/apps/desktop/src/features/score/ScoreView.test.tsx b/apps/desktop/src/features/score/ScoreView.test.tsx index de4ccb95c..7ad035f19 100644 --- a/apps/desktop/src/features/score/ScoreView.test.tsx +++ b/apps/desktop/src/features/score/ScoreView.test.tsx @@ -96,7 +96,7 @@ describe("ScoreView", () => { expect(screen.getByText("Scores attach to the active analysis project.")).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Add score" })).toBeDisabled(); - expect(screen.getByRole("button", { name: "Open score: opener.pdf" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Open score: opener.pdf" })).toHaveAttribute("aria-disabled", "true"); expect(screen.getByRole("button", { name: "Remove: opener.pdf" })).toBeDisabled(); fireEvent.click(screen.getByRole("button", { name: "Open score: opener.pdf" })); diff --git a/apps/desktop/src/features/score/ScoreView.tsx b/apps/desktop/src/features/score/ScoreView.tsx index 72732450f..9d9afa47d 100644 --- a/apps/desktop/src/features/score/ScoreView.tsx +++ b/apps/desktop/src/features/score/ScoreView.tsx @@ -184,10 +184,11 @@ export function ScoreView({ song, projectId, onSongUpdate }: ScoreViewProps) {