Rafael Camargo

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:

ElementoVariaçãoPapel
acom hreflink
asem hrefgeneric
articlearticle
asidecomplementary
blockquoteblockquote
buttonbutton
captioncaption
codecode
datalistlistbox
detailsgroup
dialogdialog
formform
h1–h6heading
hrseparator
htmldocument
imgcom alt="algum texto"img
imgcom alt=""presentation
imgsem altimg
inputtype: buttonbutton
inputtype: checkboxcheckbox
inputtype: emailtextbox
inputtype: numberspinbutton
inputtype: rangeslider
inputtype: searchsearchbox
inputtype: teltextbox
inputtype: texttextbox
inputtype: urltextbox
inputtype: text, search, tel, url, email contendo atributo listcombobox
lilistitem
menulist
metermeter
navnavigation
ollist
optgroupgroup
optionoption
outputoutput
pparagraph
progressprogressbar
selectcombobox
selectcom multiplelistbox
tabletable
tbody, tfoot, theadrowgroup
timetime
tdcontida em role=tablecell
tdcontida em role=grid ou role=treegridgridcell
thcontida em role=tablecolumnheader, rowheader ou cell
thcontida em role=grid ou role=treegridcolumnheader, rowheader ou gridcell
trrow
ullist

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.

Todo mês, uma boa dica de programação pro seu dia a dia.

Você pode ser notificado também por RSS