fix(react): address Doctor findings (#1143)

Accessibility/semantics pass aligned with React Doctor: role-based spans/divs become real buttons, role=status becomes <output>, modals use native <dialog>, author/peer flags render as <img>, and embed/challenge iframes are sandboxed. Includes review follow-ups: correct button chrome/centering/themed dialog colors and focus rings, the missing aria-label i18n keys (all languages), the Yandex image-search URL, clearer .bso setup steps, a keyboard-accessible image-search dropdown, and removal of the post-edit ('comment edited') display (mod edits unchanged).
This commit is contained in:
Tommaso Casaburi
2026-05-29 17:09:07 +07:00
committed by GitHub
parent ac95e58433
commit e082c7b428
132 changed files with 1753 additions and 1224 deletions
@@ -80,12 +80,12 @@ const render = (initialEntry = '/all/settings') => {
const getLocationText = () => container.querySelector('[data-testid="location"]')?.textContent ?? '';
const getLabelByText = (text: string) => {
const label = Array.from(container.querySelectorAll('label')).find((candidate) => (candidate.textContent ?? '').includes(text));
if (!label) {
throw new Error(`Label containing "${text}" not found`);
const getSectionToggleByText = (text: string) => {
const control = Array.from(container.querySelectorAll<HTMLElement>('label, button')).find((candidate) => (candidate.textContent ?? '').includes(text));
if (!control) {
throw new Error(`Section toggle containing "${text}" not found`);
}
return label;
return control;
};
describe('SettingsModal', () => {
@@ -115,7 +115,7 @@ describe('SettingsModal', () => {
expect(getLocationText()).toBe('/all/settings#account-settings');
await act(async () => {
getLabelByText('interface').click();
getSectionToggleByText('interface').click();
});
expect(getLocationText()).toBe('/all/settings#interface-settings');
@@ -123,14 +123,14 @@ describe('SettingsModal', () => {
expect(container.querySelector('[data-testid="account-settings"]')).not.toBeNull();
await act(async () => {
getLabelByText('interface').click();
getSectionToggleByText('interface').click();
});
expect(getLocationText()).toBe('/all/settings#account-settings');
expect(container.querySelector('[data-testid="interface-settings-panel"]')).toBeNull();
await act(async () => {
getLabelByText('bitsocial_account').click();
getSectionToggleByText('bitsocial_account').click();
});
expect(getLocationText()).toBe('/all/settings');
@@ -140,7 +140,7 @@ describe('SettingsModal', () => {
it('expands and collapses all settings sections', async () => {
render('/all/settings');
const expandAllControl = Array.from(container.querySelectorAll('[role="button"]')).find((candidate) => (candidate.textContent ?? '').includes('expand_all_settings'));
const expandAllControl = Array.from(container.querySelectorAll('button')).find((candidate) => (candidate.textContent ?? '').includes('expand_all_settings'));
if (!expandAllControl) {
throw new Error('expand_all_settings control not found');
}
@@ -157,9 +157,7 @@ describe('SettingsModal', () => {
expect(container.querySelector('[data-testid="advanced-settings-panel"]')).not.toBeNull();
expect(container.querySelector('[data-testid="p2p-stats-settings-panel"]')).not.toBeNull();
const collapseAllControl = Array.from(container.querySelectorAll('[role="button"]')).find((candidate) =>
(candidate.textContent ?? '').includes('collapse_all_settings'),
);
const collapseAllControl = Array.from(container.querySelectorAll('button')).find((candidate) => (candidate.textContent ?? '').includes('collapse_all_settings'));
if (!collapseAllControl) {
throw new Error('collapse_all_settings control not found');
}
@@ -186,7 +184,7 @@ describe('SettingsModal', () => {
it('closes the modal when the overlay is clicked', async () => {
render('/all/settings#interface-settings');
const overlay = container.querySelector('[role="button"]');
const overlay = container.querySelector('button');
if (!overlay) {
throw new Error('overlay not found');
}