Skip to content
Open
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
45 changes: 40 additions & 5 deletions src/components/launch/HudControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export const HudSystemAudioButton = memo(function HudSystemAudioButton({
<button
data-testid="launch-system-audio-button"
className={hudIconBtnClasses}
aria-label={label}
onClick={onClick}
disabled={disabled}
title={label}
Expand All @@ -184,6 +185,7 @@ export const HudMicButton = memo(function HudMicButton({
<button
data-testid="launch-microphone-button"
className={hudIconBtnClasses}
aria-label={label}
aria-pressed={enabled}
onClick={onClick}
disabled={disabled}
Expand All @@ -209,6 +211,7 @@ export const HudCameraButton = memo(function HudCameraButton({
<button
data-testid="launch-webcam-button"
className={hudIconBtnClasses}
aria-label={label}
aria-pressed={enabled}
onClick={onClick}
disabled={disabled}
Expand Down Expand Up @@ -267,6 +270,7 @@ export const HudCursorButton = memo(function HudCursorButton({
return (
<button
data-testid="launch-cursor-mode-button"
aria-label={label}
className={`flex h-[34px] w-[34px] shrink-0 items-center justify-center rounded-[10px] border-0 cursor-pointer transition-all duration-150 active:scale-95 ${hudDisabledClasses} ${styles.electronNoDrag} ${
editableOverlay
? "bg-[#10b981] text-[#08090d] hover:bg-[#0e9e6e]"
Expand Down Expand Up @@ -353,6 +357,7 @@ export const HudStudioButton = memo(function HudStudioButton({
<Tooltip content={label}>
<button
data-testid="launch-open-studio-button"
aria-label={label}
disabled={disabled}
className={`${hudIconBtnClasses} ${disabled ? "opacity-30 cursor-not-allowed pointer-events-none" : ""}`}
onClick={onClick}
Expand Down Expand Up @@ -416,18 +421,36 @@ export const HudRecordingControls = memo(function HudRecordingControls({
>
{canPause && (
<Tooltip content={pauseLabel}>
<button className={hudAuxIconBtnClasses} onClick={onTogglePause} disabled={saving}>
<button
data-testid="launch-pause-button"
className={hudAuxIconBtnClasses}
aria-label={pauseLabel}
onClick={onTogglePause}
disabled={saving}
>
{getIcon(paused ? "resume" : "pause", paused ? "text-amber-400" : "text-white/60")}
</button>
</Tooltip>
)}
<Tooltip content={restartLabel}>
<button className={hudAuxIconBtnClasses} onClick={onRestart} disabled={saving}>
<button
data-testid="launch-restart-button"
className={hudAuxIconBtnClasses}
aria-label={restartLabel}
onClick={onRestart}
disabled={saving}
>
{getIcon("restart", "text-white/60")}
</button>
</Tooltip>
<Tooltip content={cancelLabel}>
<button className={hudAuxIconBtnClasses} onClick={onCancel} disabled={saving}>
<button
data-testid="launch-cancel-button"
className={hudAuxIconBtnClasses}
aria-label={cancelLabel}
onClick={onCancel}
disabled={saving}
>
{getIcon("cancel", "text-white/60")}
</button>
</Tooltip>
Expand Down Expand Up @@ -493,10 +516,22 @@ export const HudWindowControls = memo(function HudWindowControls({
}) {
return (
<div className={`flex items-center gap-[5px] ${vertical ? "flex-col" : ""}`}>
<button className={windowBtnClasses} title={hideLabel} onClick={onHide} disabled={disabled}>
<button
className={windowBtnClasses}
title={hideLabel}
aria-label={hideLabel}
onClick={onHide}
disabled={disabled}
>
{getIcon("minimize")}
</button>
<button className={closeBtnClasses} title={closeLabel} onClick={onClose} disabled={disabled}>
<button
className={closeBtnClasses}
title={closeLabel}
aria-label={closeLabel}
onClick={onClose}
disabled={disabled}
>
{getIcon("close")}
</button>
</div>
Expand Down
48 changes: 48 additions & 0 deletions src/components/launch/LaunchWindow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ function resetLaunchMocks() {
recorderState.value.softwareEncoderFallbackNoticeVisible = false;
recorderState.value.dismissSoftwareEncoderFallbackNotice.mockClear();
recorderState.value.recording = false;
recorderState.value.canPauseRecording = false;
recorderState.value.microphoneEnabled = false;
recorderState.value.setMicrophoneEnabled.mockClear();
recorderState.value.setMicrophoneDeviceId.mockClear();
Expand Down Expand Up @@ -377,6 +378,53 @@ describe("LaunchWindow record button", () => {
expect(recorderState.value.toggleRecording).not.toHaveBeenCalled();
});

it("names the idle HUD icon controls for assistive technology", async () => {
renderLaunchWindow();
await screen.findByTestId("launch-record-button");

expect(screen.getByTestId("launch-system-audio-button")).toHaveAttribute(
"aria-label",
"Enable system audio",
);
expect(screen.getByTestId("launch-microphone-button")).toHaveAttribute(
"aria-label",
"Enable microphone",
);
expect(screen.getByTestId("launch-webcam-button")).toHaveAttribute(
"aria-label",
"Enable webcam",
);
expect(screen.getByTestId("launch-cursor-mode-button")).toHaveAttribute(
"aria-label",
"Use system cursor",
);
expect(screen.getByTestId("launch-open-studio-button")).toHaveAttribute(
"aria-label",
"Open Studio",
);
expect(screen.getByTitle("Hide HUD")).toHaveAttribute("aria-label", "Hide HUD");
expect(screen.getByTitle("Close App")).toHaveAttribute("aria-label", "Close App");
});

it("names the recording-state HUD controls for assistive technology", async () => {
recorderState.value.recording = true;
recorderState.value.canPauseRecording = true;
renderLaunchWindow();

expect(await screen.findByTestId("launch-pause-button")).toHaveAttribute(
"aria-label",
"tooltips.pauseRecording",
);
expect(screen.getByTestId("launch-restart-button")).toHaveAttribute(
"aria-label",
"tooltips.restartRecording",
);
expect(screen.getByTestId("launch-cancel-button")).toHaveAttribute(
"aria-label",
"tooltips.cancelRecording",
);
});

it("clears record-after-selection intent when the source picker closes without a selection", async () => {
renderLaunchWindow();
await waitForSourceSelectionSubscription();
Expand Down
Loading