feat(voyage): add export flow + A11Y baseline — v4.2 Step 11 [skip-docs]
Closes Wave 2 (Steps 6-11) of v4.2 implementation. Playground now
delivers the complete annotation pipeline: render -> create gestures
-> sidebar -> export.
Export flow:
- 'Eksporter batch' button in sidebar export-bar
- Export modal with role="dialog" aria-modal="true"
- Generated /trekrevise command-string ready to copy
- Two paths:
navigator.clipboard.writeText (modern) with execCommand('copy')
legacy fallback for cross-browser support
Blob + URL.createObjectURL download as annotated-{brief|plan|review}.md
- buildAnnotatedMarkdown injects voyage:anchor comments above target
lines (mirrors lib/parsers/anchor-parser.mjs addAnchors() behaviour)
Resolve-til-arkiv (Google Docs pattern, per research-06):
- Post-export marks pending drafts as exported (NOT delete)
- Tab 2 ('Alle revisjoner') surfaces history with revision-stamp
- aria-live='polite' toast announces export status
A11Y baseline (per research-06 + llm-security A11Y-RAPPORT.md):
- aria-live='polite' toast region (Step 1)
- Skip-to-main link (.visually-hidden + #main target)
- role='dialog' + aria-modal='true' on form modal (Step 9)
on export modal (Step 11)
- role='tablist' / role='tab' / aria-selected / tabindex roving (Step 10)
- aria-controls + aria-labelledby on tabpanels
- aria-pressed on intent buttons (radiogroup-like)
- aria-expanded + aria-controls on sidebar FAB
- aria-hidden='true' on decorative SVG paths
- aria-label on icon-only buttons
- .visually-hidden labels for textarea + clipboard helper
Test coverage: tests/playground/voyage-playground.test.mjs +4 cases —
aria-live='polite', Skip to main, Blob, clipboard.writeText.
Verify: node --test tests/playground/voyage-playground.test.mjs ->
22 pass / 0 fail.
Full npm test: 596 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 11 + research-06 + llm-security A11Y baseline.
This commit is contained in:
parent
125bfb02b2
commit
97b6f5406e
2 changed files with 261 additions and 0 deletions
|
|
@ -124,3 +124,25 @@ test('voyage-playground.html declares tabindex (Step 10 focus management)', () =
|
|||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /tabindex/i, 'sidebar tabs must use tabindex for keyboard focus management');
|
||||
});
|
||||
|
||||
// --- Step 11 — export flow + A11Y baseline -----------------------------
|
||||
|
||||
test('voyage-playground.html declares aria-live="polite" toast region (Step 11 A11Y)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /aria-live="polite"/, 'aria-live="polite" toast region required for status announcements');
|
||||
});
|
||||
|
||||
test('voyage-playground.html includes Skip to main link (Step 11 A11Y baseline)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /Skip to main/, 'Skip to main content link required for keyboard A11Y');
|
||||
});
|
||||
|
||||
test('voyage-playground.html uses Blob for download flow (Step 11 export)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /\bnew Blob\b/, 'Blob download path required for annotated.md export');
|
||||
});
|
||||
|
||||
test('voyage-playground.html uses clipboard.writeText for copy flow (Step 11 export)', () => {
|
||||
const text = readFileSync(HTML, 'utf-8');
|
||||
assert.match(text, /clipboard\.writeText/, 'navigator.clipboard.writeText path required for command-copy');
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue