mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
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:
1 parent
b4e44c4f6a
commit
1b7e03cd2c
3 files changed
+19
-7
No files matched your search
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"aicodeman": patch
|
||||
---
|
||||
|
||||
Response viewer: add a Copy Markdown button that copies the raw source of the newest answer (every part of its turn), so headings, lists and code fences paste intact. An empty viewer and a refused clipboard both say so.
|
||||
@@ -733,7 +733,7 @@
|
||||
<span id="responseViewerTitle">Last Response</span>
|
||||
<div class="response-viewer-actions">
|
||||
<button class="response-viewer-more" id="responseViewerMore" onclick="app.loadFullContext()">More</button>
|
||||
<button class="response-viewer-more response-viewer-copy-markdown" id="responseViewerCopyMarkdown" type="button" onclick="app.copyResponseViewerMarkdown()" title="Copy response as Markdown" aria-label="Copy response as Markdown">Copy Markdown</button>
|
||||
<button class="response-viewer-more response-viewer-copy-markdown" id="responseViewerCopyMarkdown" type="button" onclick="app.copyResponseViewerMarkdown()" title="Copy response as Markdown">Copy Markdown</button>
|
||||
<button class="response-viewer-close" onclick="app.toggleResponseViewer()">×</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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>');
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user