8729ccfcf5
- Each message is role="article"; collapsed messages (consecutive from one sender) now carry an aria-label with sender + time — previously a screen reader heard only the body with no attribution (the biggest a11y gap). Pure messageAriaLabel() reuses the existing time utils (+3 tests). - Editing a message announces "Editing message from <sender>" (ariaLabel threaded MessageEditor → CustomEditor; the main composer is unaffected). - System emoji get role="img" + aria-label from the shortcode; custom emoticons always have an accessible name. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
29 lines
1004 B
TypeScript
29 lines
1004 B
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import dayjs from 'dayjs';
|
|
import { messageAriaLabel } from './a11y';
|
|
import { timeDayMonthYear, timeHourMinute } from './time';
|
|
|
|
test('messageAriaLabel composes sender, date and time (24h)', () => {
|
|
const ts = dayjs('2026-07-01T14:30:00').valueOf();
|
|
assert.equal(
|
|
messageAriaLabel('Alice', ts, true),
|
|
`Alice, ${timeDayMonthYear(ts)} ${timeHourMinute(ts, true)}`,
|
|
);
|
|
});
|
|
|
|
test('messageAriaLabel honours the 12-hour clock preference', () => {
|
|
const ts = dayjs('2026-07-01T14:30:00').valueOf();
|
|
assert.equal(
|
|
messageAriaLabel('Bob', ts, false),
|
|
`Bob, ${timeDayMonthYear(ts)} ${timeHourMinute(ts, false)}`,
|
|
);
|
|
});
|
|
|
|
test('messageAriaLabel keeps the sender name verbatim as plain text', () => {
|
|
const ts = dayjs('2026-07-01T09:05:00').valueOf();
|
|
const label = messageAriaLabel('@user:example.org', ts, true);
|
|
assert.ok(label.startsWith('@user:example.org, '));
|
|
assert.ok(!label.includes('<'));
|
|
});
|