This Wiki page is edited by participants of the Protocols and Formats Working Group. It does not necessarily represent consensus and it may have incorrect information or information that is not supported by other Working Group participants, WAI, or W3C. It may also have some very useful information.

ARIA/Tests/Testable Statements

From Protocols and Formats Working Group Wiki
< ARIA‎ | Tests
Jump to: navigation, search


This is a page to work out testable statements for ARIA 1.0 testing. Tests will be migrated to the draft implementation report when ready.

Format definition and common reference values

Statement format guidelines

Statement has form "An ELEMENT has RESULT" where:

  • ELEMENT is a element in tag form that provides the conditions of the test.
  • If the element contains references to other elements, it uses one of the predefined elements listed below.
  • If the test needs to self-reference ELEMENT, id="0" is assigned to ELEMENT.
  • RESULT is a statement of form " accessible ROLE/STATE/PROPERTY=literal-value"

Testable statements with expected results varying by API

If the expected result of a testable statement does not vary by accessibility API, include the expected result as the final clause of the testable statement.

If the expected result is different in different APIs, the expected result in the testable statement should be "as defined". Then, provide a bulleted list following the expected results that details the results for each API. Begin each bullet with a flag to indicate the AAPI it references, as follows:

  • MSAA: MSAA + UIA Express
  • IA2: MSAA + IAccessible2
  • UIA: UIA
  • ATK: ATK/AT-SPI
  • AX: Mac OS X

Sample testable statement using this format:

An element with ... has accessible ... according to the AAPI in use, as follows.

  • MSAA: ...
  • IA2: ...
  • UIA: ...
  • ATK: ...
  • AX: ...

Predefined text values

The text values of the following given elements can be used for reference in any testable statement. Note that the included white space in the text of the elements is intentional to test the requirements for concatenation.

<h1 id="ID1">foo</h1>
<p id="ID2">bar  </p>
<a id="ID3">  baz  </a>

Definition of 'BLANK'

It is possible for the accessible name calculation to have no result. However, there is no restriction on how accessibility APIs represent a non-result. The API could use the empty string (""), or a null result. For the purpose of testable statements, this outcome is captured by stating the result is BLANK.

Accessible name computation tests

DIV Tests

Note: any text listing attributes which are specified in parentheses is optional for the test. The results should be the same whether the attribute listed is specified or not.

If given <DIV aria-labelledby="ID1">ABC</DIV> (and aria-label is not specified and title is not specified) then accessible name = "foo"

If given <DIV aria-label="Tag">ABC</DIV> and aria-labelledby is not specified (and title is not specified) then accessible name = "Tag"

If given <DIV aria-labelledby="ID1" aria-label="Tag">ABC</DIV> (and title is not specified) then accessible name = "foo"

If given <DIV id="ID0" aria-labelledby="ID0 ID1" aria-label="Tag">ABC</DIV> (and title is not specified) then accessible name = "Tag foo"

If given <DIV>ABC</DIV> and aria-label is not specified and aria-labelledby is not specified and title is not specified and role is not specified then accessible name is BLANK

If given <DIV role="button">ABC</DIV> and aria-label is not specified and aria-labelledby is not specified (and title is not specified) then accessible name = "ABC"

If given <DIV role="button" title="Tag"></DIV> and aria-label is not specified and aria-labelledby is not specified then accessible name = "Tag"

A (Link) Tests

Note: any text listing attributes which are specified in parentheses is optional for the test. The results should be the same whether the attribute listed is specified or not.

If given <A href="test.html" aria-labelledby="ID1">ABC</A> (and aria-label is not specified and title is not specified) then accessible name = "foo"

If given <A href="test.html" aria-label="Tag">ABC</A> and aria-labelledby is not specified (and title is not specified) then accessible name = "Tag"

If given <A href="test.html" aria-labelledby="ID1" aria-label="Tag">ABC</A> (and title is not specified) then accessible name = "foo"

If given <A href="test.html" id="ID0" aria-labelledby="ID0 ID1" aria-label="Tag">ABC</A> (and title is not specified) then accessible name = "Tag foo"

If given <A href="test.html">ABC</A> and aria-label is not specified and aria-labelledby is not specified (and title is not specified) then accessible name = "ABC"

If given <A href="test.html" title="Tag"></A> and aria-label is not specified and aria-labelledby is not specified then accessible name = "Tag"

IMG tests

IMG-1: If given <IMG aria-label="l"> and aria-labelledby is not specified and alt is not specified and title is not specified then accessible name = "l".

IMG-2: If given <IMG aria-label="l" alt="a" title="t">

and aria-labelledby is not specified,

then accessible name = "l".

IMG-3: If given <IMG aria-labelledby="ID1"> and aria-label is not specified and alt is not specified and title is not specified then accessible name = "foo".

IMG-4: If given <IMG aria-label="l" aria-labelledby="ID1"> and alt is not specified and title is not specified then accessible name = "foo".

IMG-5: If given <IMG id="ID0" aria-label="l" aria-labelledby="ID0 ID1"> and alt is not specified and title is not specified then accessible name = "l foo".

IMG-6: If given <IMG aria-labelledby="ID1 ID2 ID3"> and aria-label is not specified and alt is not specified and title is not specified then accessible name = "foo bar baz".

IMG-7: If given <IMG id="ID0" aria-label="l" aria-labelledby="ID0 ID1 ID2 ID3"> and alt is not specified and title is not specified then accessible name = "L foo bar baz".

IMG-8: If given <IMG id="ID0" aria-label="l" aria-labelledby="ID0 ID1 ID2 ID3" alt="a" title="t"> then accessible name = "L foo bar baz".

IMG-9: If given <IMG id="ID0" aria-label="" aria-labelledby="ID0 ID1 ID2 ID3" alt="" title="t"> then accessible name = "foo bar baz".

IMG-10: If given <IMG aria-labelledby="ID99"> and ID99 does not exist and aria-label is not specified and alt is not specified and title is not specified then accessible name is BLANK.

Not required for CR:

IMG-Optional-1: If given <IMG aria-label="l" aria-labelledby="ID99"> and ID99 does not exist and alt is not specified and title is not specified then accessible name = "l".

INPUT Tests

Definition of ANY

An INPUT element has a @type attribute that has values text, password, checkbox, radio, submit, reset, file, image, button, and hidden. The term "ANY" represents any of the values of @type, with the exceptions of hidden. The latter is a special cases and treated separately.

  • <INPUT type="ANY" aria-hidden="true"> not referenced by an aria-labelledby nor aria-describedby has an accessible name = BLANK.
  • <INPUT type="ANY" hidden="true"> not referenced by an aria-labelledby nor aria-describedby has an accessible name = BLANK.
  • <INPUT type="hidden"> not referenced by aria-labelledby nor aria-describedby has an accessible name = BLANK.
  • <INPUT type="ANY" aria-labelledby="ID1"> has an accessible name = "foo".
  • <INPUT type="ANY" aria-labelledby="ID1 ID2 ID3"> has an accessible name = "foo bar baz".
  • <INPUT type="ANY" aria-labelledby="ID1" aria-label="bar"> has an accessible name = "foo".
  • <INPUT type="ANY" id="ID0" aria-labelledby="ID1 ID0" aria-label="bar"> has an accessible name = "foo bar".
  • <INPUT type="submit"> that does not have a role="presentation" has an accessible name = "submit".
  • <INPUT type="reset"> that does not have a role="presentation" has an accessible name = "reset".
  • <INPUT type="button" value="foo"> that does not have a role="presentation" has an accessible name = "foo".
  • <INPUT type="image" alt="foo"> that does not have a role="presentation" has an accessible name = "foo".
  • <INPUT type="text" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="password" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="radio" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="file" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".
  • <INPUT type="image" id="ID0"> that is referenced by a <LABEL for="ID0">foo</LABEL> element has an accessible name = "foo".

Embedded controls -- embedded text INPUT

For reference, the following shows the structure of a label with an embedded text INPUT:

<input type="checkbox" id="id0">
<label for="id0">foo <input type="text" value="bar"> baz</label>
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded text <INPUT value="bar"> has an accessible name = "foo bar baz".
  • <INPUT type="text" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded text <INPUT value="bar"> has an accessible name = "foo bar baz".
  • <INPUT type="password" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded text <INPUT value="bar"> has an accessible name = "foo bar baz".
  • <INPUT type="radio" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded text <INPUT value="bar"> has an accessible name = "foo bar baz".
  • <INPUT type="file" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded text <INPUT value="bar"> has an accessible name = "foo bar baz".

Embedded controls -- embedded <SELECT>, @role="MENU", or @role="COMBOBOX"

For reference, the following shows the structure of a label with an embedded SELECT. Similar markup for MENU or COMBOBOX roles applies:

<input type="checkbox" id="ID0">
<label for="IDO">Flash the screen 
  <select size="1">
    <option selected="selected">1</option>
    <option>2</option>
    <option>3</option>
  </select>
  times.
</label>
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded <SELECT>, @role="MENU", or @role="COMBOBOX" whose text alternative is "1" has an accessible name = "Flash the screen 1 times".
  • <INPUT type="text" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded <SELECT>, @role="MENU", or @role="COMBOBOX" whose text alternative is "1" has an accessible name = "Flash the screen 1 times".
  • <INPUT type="password" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded <SELECT>, @role="MENU", or @role="COMBOBOX" whose text alternative is "1" has an accessible name = "Flash the screen 1 times".
  • <INPUT type="radio" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded <SELECT>, @role="MENU", or @role="COMBOBOX" whose text alternative is "1" has an accessible name = "Flash the screen 1 times".
  • <INPUT type="file" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded <SELECT>, @role="MENU", or @role="COMBOBOX" whose text alternative is "1" has an accessible name = "Flash the screen 1 times".

Embedded controls -- embedded @role="RANGE"

These testable statements involve a concrete range object embedded in a label. The two cases are @role='spinbutton' and @role='slider'.

For reference, the following shows the structure of a label with an embedded spinner control. Similar markup for a slider control applies.

<input type="checkbox" id="id1">
<label for="id1">foo <input role="spinbutton" type="text" aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz</label>
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SPINBUTTON" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="text" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SPINBUTTON" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="password" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SPINBUTTON" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="radio" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SPINBUTTON" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="file" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SPINBUTTON" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="checkbox" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SLIDER" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="text" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SLIDER" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="password" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SLIDER" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="radio" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SLIDER" whose text alternative is "5" has an accessible name = "foo 5 baz".
  • <INPUT type="file" id="ID0"> that is referenced by a <LABEL for="ID0"> that contains an embedded @role="SLIDER" whose text alternative is "5" has an accessible name = "foo 5 baz".

@title

  • <INPUT type="text" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".
  • <INPUT type="password" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".
  • <INPUT type="checkbox" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".
  • <INPUT type="radio" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".
  • <INPUT type="file" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".
  • <INPUT type="image" title="foo"> with no aria-labelledby and no aria-label, does not have a role="presentation", is not referenced by a <LABEL> element, and has a title attribute equal to "foo", has an accessible name of "foo".

CSS Content Rules

  • <INPUT type="image"> that has an associated CSS content rule that replaces the image with the text "foo" has an accessible name equal to "foo".
  • <INPUT type="ANY"> that has an associated CSS content rule that replaces old text with the new text "foo" has an accessible name equal to "foo".

For reference, assume the following CSS content rules:

input:before { content: "foo" }
input:after { content: "baz" }

Furthermore, assume that the name computation for the <INPUT> element has thus far generated "bar" as the accessible name before applying the above CSS content rules.

  • <INPUT type="text"> that has an CSS :before content rule of "foo" and an associated CSS :after rule of "baz" has an accessible name = "foo bar baz".
  • <INPUT type="password"> that has an CSS :before content rule of "foo" and an associated CSS :after rule of "baz" has an accessible name = "foo bar baz".
  • <INPUT type="checkbox"> that has an CSS :before content rule of "foo" and an associated CSS :after rule of "baz" has an accessible name = "foo bar baz".
  • <INPUT type="radio"> that has an CSS :before content rule of "foo" and an associated CSS :after rule of "baz" has an accessible name = "foo bar baz".
  • <INPUT type="file"> that has an CSS :before content rule of "foo" and an associated CSS :after rule of "baz" has an accessible name = "foo bar baz".

aria-describedby tests

An element
<img id="0" aria-describedby="ID1">
, where element ID1 is visible, has accessible description according to the AAPI in use, as follows:
  • MSAA: accDescription="foo"
  • IA2: accDescription="foo" AND IA2_RELATION_DESCRIBED_BY contains pointer to element ID1 AND IA2_RELATION_DESCRIPTION_FOR has pointerr to element 0
  • UIA:DescribedBy has pointer to element ID1
  • ATK: description="foo" and RELATION_DESCRIBED_BY has pointer to element ID1 AND RELATION_DESCRIPTION_FOR has pointer to element 0
  • AX: AXHelp="foo"
An element
<img id="0" aria-describedby="ID1">
, where element ID1 is NOT visible, has accessible description according to the AAPI in use, as follows:
  • MSAA: accDescription="foo"
  • IA2: accDescription="foo"
  • UIA: not defined (exposing property not named)
  • ATK: description="foo"
  • AX: AXHelp="foo"
An element
<img id="0" aria-describedby="ID1">
, where element ID1 is visible and has role presentation, has accessible description according to the AAPI in use, as follows:
  • MSAA: accDescription="foo"
  • IA2: accDescription="foo"
  • UIA: not defined (exposing property not named)
  • ATK: description="foo"
  • AX: AXHelp="foo"

Combobox with aria-autocomplete='list'

Context: there is proposed clarification text for the combobox role with respect to its @aria-autocomplete='list' property. The new text is for the third bullet in the combobox section explaining how to determine the currently selected value is:

  • If an author sets a combobox's value of aria-autocomplete to 'list', user agents MUST expose changes to the aria-activedescendant attribute on the combobox while the combobox remains focused. ...

The above text contains a MUST, and thereby incurs testable statements.

Using this example markup:

<input type="text" role="combobox" aria-label="Tag" aria-expanded="true"
       aria-autocomplete="list" aria-owns="owned_listbox" aria-activedescendant="selected_option">
<ul role="listbox" id="owned_listbox">
   <li role="option">Zebra</li>
   <li role="option" id="selected_option">Zoom</li>
</ul>

The testable statement is:

  • <INPUT type="text">, @role="combobox", @aria-autocomplete="list", @aria-activedescendant="selected_option", the currently selected value of the combobox is "Zoom".

For this example markup:

<div role="combobox" aria-expanded="true" aria-label="Tag"
     aria-autocomplete="list" aria-activedescendant="selected_option">
   <input type="text" role="textbox" aria-owns="owned_listbox">
   <ul role="listbox" id="owned_listbox">
     <li role="option">Zebra</li>
     <li role="option" id="selected_option">Zoom</li>
   </ul>
</div>

The testable statetment is:

  • DIV, @role="combobox", @aria-autocomplete="list", @aria-activedescendant="selected_option", the currently selected value of the combobox is "Zoom".

AT-SPI Special Case Testable Statements

AT-SPI Role

Statements are based on the UAIG role mapping table, specifically the "ATK/AT-SPI Role" column.

Because of a "SHOULD", under certain conditions, there are no testable statements for @role='listbox' nor @role='option'. This is because of their parent element. The UAIG role mapping table states that if the listbox is a child or owned by a combobox, then the AAPI role SHOULD be ROLE_MENU. Also, for @role='option': if the option's parent is a menu, then the option SHOULD have ROLE_MENU_ITEM. These are SHOULDs, not MUSTs. Hence, there is no testable statement for these conditions. (Should they be "SHOULD"?)

listbox
Element with id "test" having role listbox that is not a child of nor owned by an element with role combobox: The AAPI object has ROLE_LIST.
Element with id "test" having role listbox that is a child of or owned by an element with role combobox: The AAPI object has either ROLE_MENU or ROLE_LIST.
menuitem
Element with id "test" having role menuitem and @aria-checked not undefined: The AAPI object has role ROLE_MENU_ITEM and supports object attribute checkable:true.
option
Element with id "test" having role option and @aria-checked not undefined: The AAPI object has role ROLE_LIST_ITEM and supports object attribute checkable:true.
Element with id "test" having role option that is not a child of nor owned by an element exposed as ROLE_MENU: The AAPI object has ROLE_LIST_ITEM.
Element with id "test" having role option that is a child of or owned by an element exposed as ROLE_MENU: The AAPI object has either ROLE_MENU_ITEM or ROLE_LIST_ITEM.
tab
Element with id "test" having role tab where focus is in the associated tabpanel whose @aria-labelledby references the tab: AAPI object has ROLE_PAGE_TAB and supports SELECTED state.
textbox
Element with id "test" having role textbox and @aria-multiline is "false" or undefined: AAPI object has ROLE_ENTRY and STATE_SINGLE_LINE.

AT-SPI States and Properties

Statements are based on the UAIG state and property mapping table, specifically the "ATK/AT-SPI" column.

aria-activedescendant (states)
Element with id "test" that is a descendant of another element with an aria-activedescendant property: the AAPI object has STATE_FOCUSABLE.
Element with id "test" that is a descendant of another element with aria-activedescendant='test': the AAPI object has STATE_FOCUSABLE and STATE_FOCUSED.
aria-atomic
Element with id "test" having aria-atomic='true': The AAPI object has object attribute atomic:true AND all descendants have object attribute container-atomic:true AND all descendants have RELATION_MEMBER_OF this atomic root.
Element with id "test" having aria-atomic='false': The AAPI object has no mapping of this aria property.
aria-autocomplete
Element with id "test" having role combobox and aria-autocomplete="inline": The AAPI object has object attribute autocomplete:inline AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role combobox and aria-autocomplete="list": The AAPI object has object attribute autocomplete:list AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role combobox and aria-autocomplete="both": The AAPI object has object attribute autocomplete:both AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role combobox and aria-autocomplete="none": The AAPI object has no mapping of this state.
Element with id "test" having role text and aria-autocomplete="inline": The AAPI object has object attribute autocomplete:inline AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role text and aria-autocomplete="list": The AAPI object has object attribute autocomplete:list AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role text and aria-autocomplete="both": The AAPI object has object attribute autocomplete:both AND exposes SUPPORTS_AUTOCOMPLETION.
Element with id "test" having role text and aria-autocomplete="none": The AAPI object has no mapping of this state.
aria-checked="mixed"
Note: table says that for radio and menuitemradio roles, treat aria-checked="mixed" as "false".
Element with id "test" having role radio and aria-checked="mixed": The AAPI object has object attribute checkable:true AND clears STATE_CHECKED.
Element with id "test" having role menuitemradio and aria-checked="mixed": The AAPI object has object attribute checkable:true AND clears STATE_CHECKED.
Element with id "test" having role checkbox and aria-checked="mixed": The AAPI object has object attribute checkable:true AND exposes STATE_INDETERMINATE.
Element with id "test" having role menuitemcheckbox and aria-checked="mixed": The AAPI object has object attribute checkable:true AND exposes STATE_INDETERMINATE.
Element with id "test" having role option and aria-checked="mixed": The AAPI object has object attribute checkable:true AND exposes STATE_INDETERMINATE.
Element with id "test" having role treeitem and aria-checked="mixed": The AAPI object has object attribute checkable:true AND exposes STATE_INDETERMINATE.
aria-describedby
Note: is this covered elsewhere? If not:
Element with id "test" with aria-describedby='foo': The AAPI object has a RELATION_DESCRIBED_BY reference to the AAPI object with id 'foo'. AND, the AAPI object with id 'foo' has a RELATION_DESCRIPTION_FOR the AAPI object with id 'test'.
aria-disabled
Note: the row for aria-disabled glosses over some subtleties of AT-SPI, namely, that certain aspects of an application can be "enabled" but not "interactive", while other aspects are both. This is captured in ARIA using the distinction between widget and non-widget roles.
Element with id "test" and a role that is a subclass of widget and aria-disabled="false": The AAPI object exposes both STATE_ENABLED and STATE_SENSITIVE.
Element with id "test" and a role that is a subclass of widget and aria-disabled="true": The AAPI object clears STATE_ENABLED and STATE_SENSITIVE.
Element with id "test" and a role that is not a subclass of widget and aria-disabled="false": The AAPI object exposes state STATE_ENABLED.
Element with id "test" and a role that is not a subclass of widget and aria-disabled="true": The AAPI object clears STATE_ENABLED.
aria-expanded
Element with id "test" and aria-expanded="true": The AAPI object exposes STATE_EXPANDABLE and STATE_EXPANDED.
Element with id "test" and aria-expanded="false": The AAPI object exposes STATE_EXPANDABLE.
aria-invalid
Element with id "test" and aria-invalid="true": The AAPI object has a text container child whose contents is the string "aria-invalid='true'".
Element with id "test" and aria-invalid="spelling": The AAPI object has a text container child whose contents is the string "aria-invalid='spelling'".
Element with id "test" and aria-invalid="grammar": The AAPI object has a text container child whose contents is the string "aria-invalid='grammar'".
Element with id "test" and aria-invalid="false": Not mapped -- The AAPI object has no special text container child associated with aria-invalid.
aria-labelledby
Note: is this covered elsewhere? If not:
Element with id "test" with aria-labelledby='foo': The AAPI object has a RELATION_LABELLED_BY reference to the AAPI object with id 'foo'. AND, the AAPI object with id 'foo' has a RELATION_LABEL_FOR the AAPI object with id 'test'.
aria-level
Element with id "test" with aria-level='5': The AAPI object has object attribute level:5.
aria-live (states and properties)
Element with id "test" with aria-live='assertive': The AAPI object has object attribute live AND all descendant AAPI objects have object attribute container-live:assertive.
Element with id "test" with aria-live='polite': The AAPI object has object attribute live:polite AND all descendant AAPI objects have object attribute container-live:polite.
Element with id "test" with aria-live='off': The AAPI object has object attribute live:off AND all descendant AAPI objects have object attribute container-live:off.
aria-live (events)
Note: not sure this requires a special case for AT-SPI, but putting it here nonetheless.
Note: technically, these events are not specific to aria-live, but for any aria state or property that is associated with removals, insertions, moves, or changes.
Element with id "test" with an aria-live property: When text is removed, emit a text_changed::delete event.
Element with id "test" with aria-live property: When text is inserted, emit a text_changed::insert event.
Element with id "test" with aria-live property: When text is changed, emit a text_changed::delete event immediately followed by a text_changed::insert event.
Element with id "test" with an aria-live property: When sub-tree is hidden, emit a children_changed::remove event.
Element with id "test" with an aria-live property: When sub-tree is removed, emit a children_changed::remove event.
Element with id "test" with an aria-live property: When sub-tree is shown, emit a children_changed::add event.
Element with id "test" with an aria-live property: When sub-tree is inserted, emit a children_changed::add event.
Element with id "test" with an aria-live property: When sub-tree is moved, emit a children_changed::remove event followed by a children_changed::add.
Element with id "test" with an aria-live property: When sub-tree is changed, emit a children_changed::remove event followed by a children_changed::add.
aria-multiline
Element with id "test" with aria-multiline='true': The AAPI object sets STATE_MULTI_LINE and clears STATE_SINGLE_LINE.
Element with id "test" with aria-multiline='false': The AAPI object clears STATE_MULTI_LINE and sets STATE_SINGLE_LINE.
aria-owns
Element with id "test" with aria-owns='foo': The AAPI object with id 'foo' has a RELATION_NODE_CHILD_OF the AAPI object with id 'test'.
aria-posinset
Element with id "test" with aria-posinset='5': The AAPI object has object property posinset:5.
Element with id "test" with no aria-posinset, BUT the container has 10 objects and the "test" element is the fifth one : The User Agent calculates the value "5" and sets the AAPI object such that is has object property posinset:5.
aria-pressed
Element with id "test" with aria-pressed='true': If the AAPI object is a button, expose ROLE_TOGGLE_BUTTON, AND expose STATE_PRESSED, AND expose object property checkable:true.
Element with id "test" with aria-pressed='mixed': If the AAPI object is a button, expose ROLE_TOGGLE_BUTTON, AND expose STATE_INDETERMINATE/STATE_SYSTEM_MIXED, AND expose checkable:true.
Element with id "test" with aria-pressed='false': If the AAPI object is a button, expose ROLE_TOGGLE_BUTTON, AND expose object property checkable:true.
Element with id "test" with no aria-pressed: The AAPI object has no mapping for this case.
aria-readonly
Element with id "test" with aria-readonly='true': The AAPI object has no mapping.
Element with id "test" with aria-readonly='false': The AAPI object has STATE_EDITABLE.
aria-relevant (states and properties)
Element with id "test" with aria-relevant='additions': The AAPI object has object attribute relevant:additions AND all descendant AAPI objects have object attribute container-relevant.
Element with id "test" with aria-relevant='removals': The AAPI object has object attribute relevant:removals AND all descendant AAPI objects have object attribute container-relevant.
Element with id "test" with aria-relevant='all': The AAPI object has object attribute relevant:all AND all descendant AAPI objects have object attribute container-relevant.
Element with id "test" with aria-additions='text all': The AAPI object has object attribute relevant:additions text AND all descendant AAPI objects have object attribute container-relevant.
aria-relevant (events)
Note: not sure this requires a special case for AT-SPI, but putting it here nonetheless.
Note: technically, these events are not specific to aria-relevant, but for any aria state or property that is associated with removals, insertions, moves, or changes.
Element with id "test" with an aria-relevant property: When text is removed, emit a text_changed::delete event.
Element with id "test" with aria-relevant property: When text is inserted, emit a text_changed::insert event.
Element with id "test" with aria-relevant property: When text is changed, emit a text_changed::delete event immediately followed by a text_changed::insert event.
Element with id "test" with an aria-relevant property: When sub-tree is hidden, emit a children_changed::remove event.
Element with id "test" with an aria-relevant property: When sub-tree is removed, emit a children_changed::remove event.
Element with id "test" with an aria-relevant property: When sub-tree is shown, emit a children_changed::add event.
Element with id "test" with an aria-relevant property: When sub-tree is inserted, emit a children_changed::add event.
Element with id "test" with an aria-relevant property: When sub-tree is moved, emit a children_changed::remove event followed by a children_changed::add.
Element with id "test" with an aria-relevant property: When sub-tree is changed, emit a children_changed::remove event followed by a children_changed::add.
aria-selected (events)
Element with id "test" whose aria-selected is toggled between true and false, and is a descendant of an element with aria-multi-selectable='false' where selection follows focus: emit an object::selection_changed event but arrange events so that it does not occur on the focussed item.
Element with id "test", whose aria-selected is toggled between true and false, and is a descendant of an element with aria-multi-selectable='true': emit an object::selection_changed event on the AAPI object.
Element with id "test", whose aria-selected is toggled between true and false, and is a descendant of an element with aria-multi-selectable='true' where selection follows focus: emit an object::selection_changed event but arrange events so that it does not occur on the focussed item.
Element with id "test", whose aria-selected is toggled between true and false, and is a descendant of an element with aria-multi-selectable='true' and where many items' selection is toggled: emit a object::selection_changed event for each AAPI object whose selections changes (note: UAIG says that these multiple selection_changed events MAY be trimmed).
aria-setsize
Element with id "test" with aria-setsize='5': The AAPI object has object attribute setsize:5.
Element with id "test", with no aria-setsize property, whose role supports aria-setsize, and has 5 DOM children: The AAPI object has object attribute setsize:5.
aria-sort
Element with id "test" with aria-sort='ascending': The AAPI object has object attribute sort:ascending.
Element with id "test" with aria-sort='descending': The AAPI object has object attribute sort:descending.
Element with id "test" with aria-sort='other': The AAPI object has object attribute sort:other.
Element with id "test" with aria-sort='none': The AAPI object has object attribute sort:none.
Element with id "test" with no aria-sort property: The AAPI object has no mapping.
aria-valuemax
Note: the UAIG does not document how the AtspiValue interface is filled in.
Element with id "test" with aria-valuemax='5': The AAPI object's AtspiValue maxiumum property is 5.0.
Element with id "test" with aria-valuemax=' ': The AAPI object's AtspiValue maxiumum property is 0.0.
Element with id "test" with no aria-valuemax property: The AAPI object's AtspiValue maxiumum property is 0.0.
aria-valuemin
Note: the UAIG does not document how the AtsipValue interface is filled in.
Element with id "test" with aria-valuemin='5': The AAPI object's AtspiValue miniumum property is 5.0.
Element with id "test" with aria-valuemin=' ': The AAPI object's AtspiValue miniumum property is 0.0.
Element with id "test" with no aria-valuemin property: The AAPI object's AtspiValue miniumum property is 0.0.
aria-valuenow
Note: the UAIG does not document how the AtsipValue interface is filled in.
Element with id "test" with aria-valuenow='5': The AAPI object AtspiValue miniumum property is 5.0.
Element with id "test" with aria-valuenow=' ': The AAPI object AtspiValue miniumum property is 0.0.
Element with id "test" with no aria-valuenow property: The AAPI object AtspiValue miniumum property is 0.0.
aria-valuetext
Element with id "test" with aria-valuetext="Monday": The AAPI object has object property valuetext:Monday.

User Agent Implementation Guide Testable Statements

The following testable statements were developed during the 6 March 2012 PF Face to Face meeting.

Note: specify that all elements have accessible names set i.e., text values

keyboard-focus

  • a element with tabindex="-1" and a script buttun to focus it : element is removed from tab order but can receive focus by script
  • span element with tabindex="-1" and a script buttun to focus it : element is not in tab order but can receive focus by script
  • span element with tabindex="0" and a script button to focus it : element is in tab order and can receive focus by script
  • a element with tabindex="0" and a script button to focus it : element is in tab order and can receive focus by script
  • span element with tabindex="-1" : element appears in accessibility tree and has focusable state set to true
  • span element with tabindex="0" : element appears in accessibility tree and has focusable state set to true
  • input element type="button" with tabindex="0" : element appears in accessibility tree and has focusable state set to true
  • input element type="button" with tabindex="-1" : element appears in accessibility tree and has focusable state set to true

keyboard-focus_tabindex

  • #1 and #2 covered from above
  • #3:
    • a element with tabindex=1 followed by span with tabindex=2 followed by a with tabindex=3 : each element has a focusable state set to true and user can navigate by keyboard in sequential order
  • #4:
    • a element with tabindex="0" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=0
    • a element with tabindex="1" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=1
    • a element with tabindex="-1" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=-1
    • span element with tabindex="0" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=0
    • span element with tabindex="1" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=1
    • span element with tabindex="-1" and script that informs of the element's tabindex value from the DOM element.tabindex property : element.tabindex=-1
  • #5 and #6:
    • On a page having an a element with tabindex=0 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
    • On a page having an a element with tabindex=-1 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
    • On a page having an a element with tabindex=1 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
    • On a page having a span element with tabindex=0 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
    • On a page having a span element with tabindex=-1 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
    • On a page having a span element with tabindex=1 and a script that sets focus to it with element.focus and a DOMFocusIn event listener which reports that focus was set : focus is successfully reported
  • #7:
    • On an a element with tabindex=0 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
    • On an a element with tabindex=-1 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
    • On an a element with tabindex=1 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
    • On a span element with tabindex=0 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
    • On a span element with tabindex=-1 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
    • On a span element with tabindex=1 having a keypress event listener that reports it was fired and a keydown event listener that cancels event propagation, press a key : keypress event is not fired
  • #8: focusable cases covered by #1;
    • p element with no tabindex attribute : focusable state is false
  • #9:
    • a element with focus set : focused state is true
    • a element with focus not set : focused state is false
  • #10:
    • span element with tabindex=0 and a click event listener that reports it was fired but no key event listener, tab to the element and press enter : the click event listener report is observed
    • span element with tabindex=1 and a click event listener that reports it was fired but no key event listener, tab to the element and press enter : the click event listener report is observed
  • #11: {removing this requirement}

keyboard-focus_aria-activedescendant

  • #1: covered from tabindex section
  • #2:
    • div element with role="menu" and tabindex=0 and aria-activedescendant that references a descendant div element with role="menuitem", set focus on the menu : focused state is not set on the menu
  • #3:
    • div element with role="menu" and tabindex=0 and aria-activedescendant that references one of two descendant div elements with role=menuitem, and script that changes aria-activedescendant value of menu from one of the menuitems to the other : focused state is removed from the first menuitem and a desktop focus event is fired on the second menuitem
    • div element with role="menu" and tabindex=0 and aria-activedescendant referencing a descendant div element with role=menuitem, and script that removes aria-activedescendant from the menu : a desktop focus event is fired on the menu
    • div element with role="menu" and tabindex=0 and aria-activedescendant referencing a descendant div element with role=menuitem, and script that aria-activedescendant on the menu to a non-valid id reference : a desktop focus event is fired on the menu
  • #4:
    • div element with role="menuitem" whose ID is referenced by the aria-activedescendant of an ancestor div element with role="menu" : focusable property is set on the menuitem
    • two div elements with role="menuitem", one of which has an id referenced by the aria-activedescendant of an ancestor div element with role="menu" : focused property of the referenced menuitem is set and focusable property of the the other menuitem is set

keyboard-focus_at

  • two focusable elements with focus event that reports focus was set, one of which is focused, use accessibility api request to change focus to the other element : focus change is reported
  • div element with role=menu and two descendant div elements with role=menuitem" and a focus event handler that reports it received focus, and another focusable element on the page that has initial focus, use accessibility api request to set focus on one of the menuitems : the menu reports receiving focus
  • div element with role=menu and two descendant div elements with role=menuitem" and a focus event handler that reports it received focus, and another focusable element on the page that has initial focus, use accessibility api request to set focus on one of the menuitems : a desktop focus event is fired on the accessibility tree object that corresponds to the menuitem on which focus request was made and the same accessibility tree object has the focused state set

include_elements

  • #1: div element with text node of "content text": "content text" is in the accessibility tree
  • #2:
    • 4.1. Focus States and Events Table
    • 5.8.2. Changes to document content or node visibility
    • 5.8.3. Selection
    • 5.8.4. Special Events for Menus
  • #3:
    1. covered by presentation tests, and reverse by the other tests
  • #4:
    • a element with href attribute : element appears in the AAPI tree
    • Span element with tabindex=0 : element appears in the AAPI tree
    • Div element with role=menuitem referenced by aria-activedescendant of ancestor div with role=menu : menuitem appears in the AAPI tree
  • #5: @@under rewrite
  • #6: @@under rewrite
  • #7: @@under rewrite

exclude_elements

covered by presentation tests

mapping_conflicts

  • input with type=text and role=spinbutton : role is spinbutton
  • input with type=checkbox and role=spinbutton : role is spinbutton
  • input with type=checkbox but checked attribute not set and aria-checked=true : checked state is false

other testable statements are HTML 5

mapping_nodirect

mostly covered by mapping table

  • div element with role="grid checkbox" :
    • MSAA: {can't meet}
    • IA2: AAPI tree element is ROLE_SYSTEM_TABLE and xml-roles is "grid checkbox"
    • UIA: AriaRole property is "grid checkbox" and AAPI tree element is DataGrid
    • ATK/SPI: AAPI tree element is ROLE_ TABLE and xml-roles is "grid checkbox"
    • AXAPI: AXTable <nil> 'table'

mapping_role

  • div element with role="foobar checkbox" : element mapped as for checkbox
  • div element with role="checkbox foobar" : element mapped as for checkbox
  • #1: ##about scripts, covered by other tests
  • #2: ##abstract covered
  • #3:
    • table element with role="foo" : element mapped as for table
    • Input type="text" with role="bar" : element mapped as for text input
  • #4: ##presentation
  • #5: ##covered above

mapping_state-property

  • input type="checkbox" aria-labelledby referencing a div : input element is exposed as a checkbox and accessible name is content of the referenced div

mapping_additional_nd_name

covered by text alternatives tests

HTML note:

  • img with src and role=presentation and tabindex=-1 (to make it focusable and therefore appear in the accessibility tree) : accessible name is empty string
  • img with src and alt="" : accessible name is empty string
  • img with src and aria-label="" : accessible name is empty string
  • img with src and aria-labelledby="" : accessible name is empty string
  • img with src and title="" : accessible name is empty string
  • img with src and no other attributes : accessible name is null

mapping_additional_widget-value

(for the Exposure of aria-valuenow tests)

  • Div with role="spinbutton" with aria-valuenow="5", aria-valuemin="0" and aria-valuemax="10", and valuetext="nurthen" : value is "nurthen"
  • Div with role="spinbutton" with aria-valuenow="5", aria-valuemin="0" and aria-valuemax="10", and no aria-valuetext : value is "5"

mapping_additional_relations_reverse_relations

  • div with role="button" with aria-controls referencing ID of a div with role="document" : [IAccessible2] document has IA2_RELATION_CONTROLLED_BY that references the button [AT-SPI] document has RELATION_CONTROLLED_BY that references the button
  • div with role="button" with aria-describedby referencing ID of a div with role="document" : [IAccessible2] document has IA2_RELATION_DESCRIPTION_FOR that references the button [AT-SPI] document has RELATION_DESCRIPTION_FOR that references the button
  • div with role="button" with aria-flowto referencing ID of a div with role="document" : [IAccessible2] document has IA2_RELATION_FLOW_FROM that references the button [AT-SPI] document has RELATION_FLOW_FROM that references the button
  • div with role="button" with aria-labelledby referencing ID of a div with role="document" : [IAccessible2] document has IA2_RELATION_LABEL_FOR that references the button [AT-SPI] document has RELATION_LABEL_FOR that references the button
  • div with role="button" with aria-owns referencing ID of a div with role="document" : [IAccessible2] document has IA2_RELATION_NODE_CHILD_OF that references the button [AT-SPI] document has RELATION_NODE_CHILD_OF that references the button
  • label element with value of "foo" and for attribute referencing an input element with type="text". The input element also has an aria-labelledby that references a div with value of "baz" : labelledby of input references the div element with value "baz" only.

mapping_additional_position

  • div element with role="tree" which has a child div with role="treeitem" which in turn has a child div with role="group" which in turn has a child div with role="treeitem" : level of innermost treeitem is 2
  • div element with role="tree" which has an aria-owns property referencing ID of another div with role="treeitem" which in turn has an aria-owns property referencing ID of another div with role="group" which in turn has an aria-owns property referencing ID of another div with role="treeitem" : level of last treeitem is 2 (removed this test, will need AAPI specific representations if we revive)
  • div element with role="tree" which has a child div with role="treeitem" which in turn has a child div with role="group" which in turn has two child divs with role="treeitem" : first innermost treeitem has posinset of 1 and setsize of 2, and second innermost treeitem has posinset of 2 and setsize of 2
  • div element with role="tree" which has an aria-owns property referencing ID of another div with role="treeitem" which in turn has an aria-owns property referencing ID of another div with role="group" which in turn has an aria-owns property referencing ID of another div with role="treeitem" : first owned treeitem has posinset of 1 and setsize of 2, and second owned treeitem has posinset of 2 and setsize of 2 (removed this test, will need AAPI specific representations if we revive)

mapping_events_state-change

autogenerate for table: test files have a button controlling a div with appropriate role and triggering the respective change

mapping_events_visibility

For each row in first table:

  • Div element with role="document" and aria-live="assertive" and aria-relevant="all" and button to [insert | delete | text] in the div : event fired as per table

2nd table

  • @@ for Mac testing, add test for when the elements of interest are contained in a live region
  • first row
    • ul element which contains at two li elements, and a button that hides the ul element by setting style="display:none" : events fired on the ul element as per table
    • ul element which contains at two li elements, and a button that hides the ul element by setting style="visibility:hidden" : events fired on the ul element as per table
    • ul element which contains at two li elements, and a button that hides the ul element by setting aria-hidden="true" : events fired on the ul element as per table
  • second row
    • ul element which contains at two li elements, and a button that removes the ul element from the DOM : events fired on the ul element as per table
  • third row
    • ul element which contains at two li elements, and a button that shows the ul element by setting style="display:block" : events fired on the ul element as per table
    • ul element which contains at two li elements, and a button that shows the ul element by setting style="visibility:visible" : events fired on the ul element as per table
    • ul element which contains at two li elements, and a button that shows the ul element by setting aria-hidden="false" : events fired on the ul element as per table
  • fourth row
    • div element with role="document" and button that inserts a ul element with two li child elements as a child of the div : events fired on the div element as per table
  • fifth row
    • two div elements with role="region", one of which contains a ul element with two li child elements, and button that moves the ul element and its children to the other div : events fired on both div elements as per table
  • sixth row
    • div element with role="document" which contains a ul element with two li child elements and button that replaces the ul with a p element : events fired on the div element as per table

mapping_events_selection

  • single selection:
    • div element with role="listbox" and child div with role="option" and tabindex="0", set focus to the option : selection event fired per API
  • table element with role="grid" with a child tr with role="row" with two child td elements with role="gridcell" and tabindex="0" and text contents, set focus on the first one : selection event fired per API on the gridcell
    • table element with role="grid" with a child tr with role="row" and tabindex="0" with two child td elements with role="gridcell" and text contents, set focus on the row : selection event fired per API on the row
    • table element with role="tablist" with a child tr with role="presentation" with two child td elements with role="tab" and tabindex="0" and text contents, set focus on the first one : selection event fired per API on the gridcell
  • multi selection:
    • div element with role="listbox" and aria-multiselectable="true" having two child div elements with role="option", the first one having aria-selected="true" and the second having aria-selected="false" and onload handler for page that sets aria-selected="true" on the second option : selection events fired per API on the second option
    • div element with role="listbox" and aria-multiselectable="true" having two child div elements with role="option" and aria-selected="true" and onload handler for page that sets aria-selected="false" on the second option : selection events fired per API on the second option
    • div element with role="listbox" and aria-multiselectable="true" having two child div elements with role="option" and tabindex="0" and aria-selected="false" and onload handler for page that sets aria-selected="true" on the second option : selection events fired per API on the second option
    • div element with role="listbox" and aria-multiselectable="true" having three child div elements with role="option" and aria-selected="false" , click on the first option, then shift-click on the third option and script that enables focus with click on options and shift-click for range selection : selection events fired per API on all three options

mapping_events_menus

  • div element with role="menubar" and child div with role="menuitem" with aria-haspop="true" and aria-owns with value referencing ID of a div outside the menubar whose role="menu" and style="display:none:" containing two divs with role="item" and text contents, with onload script that sets style="display:block" on the menubar : menu start events fired per API on the menubar div
  • div element with role="menubar" and child div with role="menuitem" with aria-haspop="true" and aria-owns with value referencing ID of a div outside the menubar whose role="menu" and style="display:none:" containing two divs with role="item" and text contents, with onload script that sets style="display:block" on the menubar and sets focus on the first item in the menu : focus events fired per API on the item div
  • div element with role="menubar" and child div with role="menuitem" with aria-haspop="true" and aria-owns with value referencing ID of a div outside the menubar whose role="menu" and style="display:none:" containing two divs with role="item" and text contents, with onload script that sets style="display:block" on the menubar and sets focus on the first item in the menu : popupstart events fired per API on the menu div
  • div element with role="menubar" and child div with role="menuitem" with aria-haspop="true" and aria-owns with value referencing ID of a div outside the menubar whose role="menu" and style="display:block:" containing two divs with role="item" and text contents, with onload script that sets style="display:none" on the internal menubar and sets focus on an element outside the menu : menupopupend and menuend events fired per API on the outer menubar div

document-handling_css-selectors

  • two div elements with aria-haspopup="true", and style rule on page that says div[aria-haspop="true"] {background-color : red} : the background of div elements is red
  • two div elements with aria-haspopup="false", and style rule on page that says div[aria-haspop="true"] {background-color : red} : the background of div elements is the default page background
  • two div elements with aria-haspopup="true", and style rule on page that says div[aria-haspop="true"] {background-color : red}, and script that sets aria-haspopup to false on the second the div elements : the background of second div element is the default page background

document-handling_author-errors

  • on a user agent that has passed a test resolving aria-describedby
  • div element with aria-describedby="broken" where there is no element with an ID of "broken" on the page : no relationship for describedby exposed and no accessible description exposed
  • div element with aria-describedby="broken brokenmore" where there is no element with an ID of "broken" nor of "brokenmore" on the page : no relationship for describedby exposed and no accessible description exposed
  • div element with aria-describedby="broken worky" where there is no element with an ID of "broken" on the page but there is a div element with ID "worky" and text "this works": describedby references worky only and accessible description is "this works"