Usando Testing Library com ARIA roles implícitos
Escrever testes que interajam com os elementos da tela através de seus papéis (roles) é uma boa estratégia para assegurar a correta semântica de um documento HTML.
Em termos de estrutura e acessibilidade, é crucial que um título desempenhe o papel de heading, que um select desempenhe o papel de combobox—ou listbox—, que um textarea desempenhe papel de textbox, e assim por diante. Porém, quando o atributo aria-role não está explicitamente declarado em um elemento, nem sempre é fácil descobrir qual papel está implicitamente associado a ele.
A seguinte tabela exibe os papéis (roles) que estão implicitamente associados a muitos elementos frequentemente usados em um documento HTML:
Elemento | Variação | Papel |
---|---|---|
a | com href | link |
a | sem href | generic |
article | article | |
aside | complementary | |
blockquote | blockquote | |
button | button | |
caption | caption | |
code | code | |
datalist | listbox | |
details | group | |
dialog | dialog | |
form | form | |
h1–h6 | heading | |
hr | separator | |
html | document | |
img | com alt="algum texto" | img |
img | com alt="" | presentation |
img | sem alt | img |
input | type: button | button |
input | type: checkbox | checkbox |
input | type: email | textbox |
input | type: number | spinbutton |
input | type: range | slider |
input | type: search | searchbox |
input | type: tel | textbox |
input | type: text | textbox |
input | type: url | textbox |
input | type: text, search, tel, url, email contendo atributo list | combobox |
li | listitem | |
menu | list | |
meter | meter | |
nav | navigation | |
ol | list | |
optgroup | group | |
option | option | |
output | output | |
p | paragraph | |
progress | progressbar | |
select | combobox | |
select | com multiple | listbox |
table | table | |
tbody, tfoot, thead | rowgroup | |
time | time | |
td | contida em role=table | cell |
td | contida em role=grid ou role=treegrid | gridcell |
th | contida em role=table | columnheader, rowheader ou cell |
th | contida em role=grid ou role=treegrid | columnheader, rowheader ou gridcell |
tr | row | |
ul | list |
Conhecer o papel implícito dos elementos HTML facilita o uso da função getByRole
, disponibilizada pela Testing Library, quando se quer obter um elemento através de seu papel:
it('should contain a link to the blog', () => {
const { getByRole } = render(<MyCustomComponent />);
const link = getByRole('link', { name: 'Blog' });
expect(link).toHaveAttribute(
'href',
'https://rafaelcamargo.com/blog/l/pt-BR/'
);
});
É importante estar ciente que, dependendo da quantidade de elementos presentes na tela renderizada, encontrar um elemento através de seu papel (role) pode retardar a execução do teste. Nesses casos, uma alterantiva para evitar possíveis problemas de performance é reduzir o escopo da varredura feita pela função getByRole
a uma pequena porção da tela através da função within
:
it('should contain a link to the blog', () => {
const { container } = render(<MyCustomComponent />);
const section = container.querySelector('#linkSection');
const link = within(section).getByRole('link', { name: 'Blog' });
expect(link).toHaveAttribute(
'href',
'https://rafaelcamargo.com/blog/l/pt-BR/'
);
});
Caso você esteja pensando em definir explicitamente atributos aria-role aos elementos acima contendo seus respectivos valores implícitos, saiba que isso não é recomendado. Para visualizar a lista completa dos elementos HTML e seus papéis implícitos, visite a documentação oficial.