elm-html-test
elm-html-test copied to clipboard
Have a way to extract an attribute on a found element
(This is extracted from https://github.com/eeue56/elm-html-test/issues/32.)
Sometimes it’s useful to be able to extract an attribute on a found element, and use its value in a subsequent assertion or query.
One particular case that I have stumbled upon is with WAI-ARIA attributes where I wanted to verify that a widget’s pieces are in a state that makes sense.
For example, I have a combobox widget. I want to verify that when it has aria-expanded="true", then its listbox has style="display: block", where its listbox is defined by the ID in its aria-owns attribute, which is a generated unique string because I can have multiple comboboxes in a form. Something like this:
<div role="combobox" aria-owns="owned_listbox_5" aria-expanded="true" aria-haspopup="listbox" aria-label="Tag">
<input type="text" aria-autocomplete="list" aria-controls="owned_listbox_5" aria-activedescendant="selected_option_5">
</div>
<ul role="listbox" id="owned_listbox_5">
<li role="option">Zebra</li>
<li role="option" id="selected_option_5">Zoom</li>
</ul>
I want to test that when aria-expanded="true" on the div[role="combobox"], then its ul[role="listbox"] has the style of display: block.
So to test that I have to:
- find the
div[role="combobox"] - get its
aria-ownsattribute - use that value to find the listbox and assert its style.
More generally, there are HTML elements that have attributes of type IDREFS — meaning that they refer to one or more other elements by their id attribute:
<label>’sforattribute refers to a form field<input>’slistattribute refers to a<datalist><input>’sformattribute refers to a<form><a>’shrefattribute can refer to any ID on the page in its#some-idform<td>’sheadersattribute refers to one or more<th>.
Hypothetically, one could want to verify that an <input>’s label is properly bound, and so would need to:
- find the
<input> - read its ID (which can be a generated unique string)
- use the ID to try to find the label and make assertions on it.
Similarly, WAI-ARIA defines IDREFS attributes that can technically be on any element:
aria-activedescendantaria-controlsaria-describedbyaria-detailsaria-errormessagearia-flowtoaria-labelledbyaria-owns
A hypothetical example could be that if I put an invalid value in a field, I want to verify that its corresponding error element exists, and has the appropriate style and text. To test that I’d need to:
- get that field’s
aria-errormessageattribute - find the element with that ID and make assertions on its style and text.
Got it! So maybe a way to sum up the use case here is:
- It makes sense for some functions that return
Htmlto generateidvalues for their child elements. - It makes sense to test that these
idvalues are being wired up properly. - It's undesirable for these tests to be brittle to implementation details in how the ids are generated. All they want to test is the wiring, not the
idgeneration algorithm itself.
Introducing a way to read attributes from found elements and use them to build an Expectation would address these use cases.
Does that sound like an accurate representation of the situation?
Yep! 🤓
Is it a safe assumption that the attribute would always be a String?
IDREFS will always be a string, but are there other potential types we might care about?
I think it’s safe to assume a string. 🤔
Cool! I'm gonna take a crack at an implementation this Friday - something to address both this and https://github.com/eeue56/elm-html-test/issues/52
Any objections @eeue56?
Ran into another example of this today, where we want to find an <a> tag with particular text, then grab the href, and parse the href as a route to get the onRouteChanged msg from.
@rtfeldman did you get anywhere on an implementation of this? I might like to take a crack at it myself.