fix(response-viewer): the Copy Markdown button is named by the words on it, and the full view's fallback has a test (#810)

The button's aria-label replaced its visible text as the accessible name with
a sentence that does not contain "Copy Markdown" (WCAG 2.5.3, Label in Name),
so a voice-control user could not say what they see. The label is gone and the
sentence stays as the title.

No test reached the line that keeps the brief view's answer when the full view
holds no answer of its own: the existing case returns earlier, on an empty
list. A full view that holds only a prompt reaches it.

The PR's own changeset is folded into the 1.51.0 one.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-12 02:21:08 +01:00
1 parent b4e44c4f6a
commit 1b7e03cd2c
3 files changed
+19 -7

No files matched your search

+18 -1
View File
@@ -178,6 +178,18 @@ describe('what Copy Markdown copies', () => {
await app.copyResponseViewerMarkdown();
expect(app._copyText).toHaveBeenCalledWith('the answer on screen');
});
it('keeps the brief answer when the full view holds a prompt and no answer of its own', async () => {
mountViewer();
const app = makeApp(
{ text: 'the brief answer' },
{ messages: [{ kind: 'prompt', role: 'user', text: 'a question', turn: 1 }] }
);
await app.toggleResponseViewer();
await app.loadFullContext();
await app.copyResponseViewerMarkdown();
expect(app._copyText).toHaveBeenCalledWith('the brief answer');
});
});
describe('what Copy Markdown reports', () => {
@@ -255,7 +267,12 @@ describe('Copy Markdown markup, layout and strings', () => {
const tag = actions.match(/<button[^>]*id="responseViewerCopyMarkdown"[^>]*>/)?.[0] ?? '';
expect(tag).toContain('type="button"');
expect(tag).toContain('onclick="app.copyResponseViewerMarkdown()"');
expect(tag).toContain('aria-label="Copy response as Markdown"');
expect(tag).toContain('title="Copy response as Markdown"');
// The words on the button are its accessible name (WCAG 2.5.3, Label in
// Name): an aria-label would replace them with a name that does not
// contain "Copy Markdown", so a voice-control user could not say what
// they see. The longer sentence stays as the title.
expect(tag).not.toContain('aria-label');
expect(actions).toContain('>Copy Markdown</button>');
});