import React from 'react';
import {
defaultHTMLElementModels,
HTMLContentModel,
TBlock
} from '@native-html/transient-render-engine';
import { render } from '@testing-library/react-native';
import AccessibilityEngine from 'react-native-accessibility-engine';
import RenderHTML from '../RenderHTML';
import { CustomRendererProps } from '../shared-types';
describe('RenderHTML a11y', () => {
describe('regarding anchors', () => {
describe('should add accessibility features to anchors when href is non-empty', () => {
const snippets = [
// Block
`test`,
// Inline
`test other text`
];
for (const snippet of snippets) {
it(`should pas snippet "${snippet}"`, () => {
const element = (
);
const { getByTestId } = render(element);
const anchor = getByTestId('a');
expect(anchor).toHaveProp('accessibilityRole', 'link');
expect(anchor).toHaveProp('accessible', true);
expect(() => AccessibilityEngine.check(element)).not.toThrow();
});
}
});
it('should not add accessibility features to anchors when href is empty', () => {
const element = (
test`
}}
debug={false}
contentWidth={0}
/>
);
const { getByTestId } = render(element);
const anchor = getByTestId('a');
expect(anchor).not.toHaveProp('accessibilityRole');
expect(anchor).not.toHaveProp('accessible');
expect(() => AccessibilityEngine.check(element)).not.toThrow();
});
});
describe('regarding headings', () => {
it("should add accessibility role 'header' to headings", () => {
for (const header of ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']) {
const element = (
test${header}>`
}}
debug={false}
contentWidth={0}
/>
);
const { getByTestId } = render(element);
expect(getByTestId(header)).toHaveProp('accessibilityRole', 'header');
expect(() => AccessibilityEngine.check(element)).not.toThrow();
}
});
});
describe('regarding images', () => {
it('should provide accessibility properties to
renderer when alt attribute is defined', async () => {
const element = (
'
}}
debug={false}
contentWidth={200}
/>
);
const { getByA11yRole, findByTestId } = render(element);
await findByTestId('image-success');
const image = getByA11yRole('image');
expect(image).toHaveProp('accessibilityRole', 'image');
expect(image).toHaveProp('accessibilityLabel', 'An image');
// Waiting for AccessibilityEngine to support async udpates
// see https://github.com/aryella-lacerda/react-native-accessibility-engine/issues/97
// await waitFor(() =>
// expect(() => AccessibilityEngine.check(element)).not.toThrow()
// );
});
it('
should not be accessible when alt attribute is missing', async () => {
const element = (
'
}}
debug={false}
contentWidth={200}
/>
);
const { getByTestId, findByTestId } = render(element);
await findByTestId('image-success');
const image = getByTestId('img');
expect(image).toHaveProp('accessibilityRole', 'none');
expect(image).not.toHaveProp('accessibilityLabel');
// Waiting for AccessibilityEngine to support async udpates
// see https://github.com/aryella-lacerda/react-native-accessibility-engine/issues/97
// await waitFor(() =>
// expect(() => AccessibilityEngine.check(element)).not.toThrow()
// );
});
});
describe('regarding pressable custom renderers', () => {
it('should add a button role if onPress is defined for custom renderers with a block content model', () => {
const element = (
'
}}
customHTMLElementModels={{
...defaultHTMLElementModels,
button: defaultHTMLElementModels.button.extend({
contentModel: HTMLContentModel.block
})
}}
renderers={{
button: ({
TDefaultRenderer,
...props
}: CustomRendererProps) => (
{}} {...props} />
)
}}
debug={false}
contentWidth={200}
/>
);
const { getByA11yRole } = render(element);
const button = getByA11yRole('button');
expect(button).toHaveProp('accessibilityRole', 'button');
expect(() => AccessibilityEngine.check(element)).not.toThrow();
});
it('should add a button role if onPress is defined for custom renderers with a textual content model', () => {
const element = (
'
}}
customHTMLElementModels={{
...defaultHTMLElementModels,
customlink: defaultHTMLElementModels.span
}}
renderers={{
customlink: ({
TDefaultRenderer,
...props
}: CustomRendererProps) => (
{}} {...props} />
)
}}
debug={false}
contentWidth={200}
/>
);
const { getByA11yRole } = render(element);
const button = getByA11yRole('link');
expect(button).toHaveProp('accessibilityRole', 'link');
expect(() => AccessibilityEngine.check(element)).not.toThrow();
});
});
});