chromium/third_party/blink/web_tests/accessibility/aria-activedescendant.html

<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>

<div id="contenteditable-combobox" role="combobox" contenteditable="true"
    aria-expanded="true" aria-haspopup="menu" aria-autocomplete="list"
    aria-activedescendant="list1-option1">
    <ul id="list1" role="listbox">
        <li id="list1-option1" role="option">Option 1</li>
        <li id="list1-option2" role="option">Option 2</li>
        <li id="list1-option3" role="option">Option 3</li>
    </ul>
</div>

<input id="input-combobox" role="combobox" type="text" aria-expanded="true"
    aria-haspopup="menu" aria-autocomplete="list"
    aria-activedescendant="list2-option1" aria-owns="list2">

<ul id="list2" role="listbox">
    <li id="list2-option1" role="option">Option 1</li>
    <li id="list2-option2" role="option">Option 2</li>
    <li id="list2-option3" role="option">Option 3</li>
</ul>

<input id="input-searchbox" role="combobox" type="search" aria-expanded="true"
    aria-haspopup="menu" aria-autocomplete="list"
    aria-activedescendant="list3-option1" aria-owns="list3">

<ul id="list3" role="listbox">
    <li id="list3-option1" role="option">Option 1</li>
    <li id="list3-option2" role="option">Option 2</li>
    <li id="list3-option3" role="option">Option 3</li>
</ul>

<textarea id="textarea-combobox" role="combobox" aria-expanded="true"
    aria-haspopup="menu" aria-autocomplete="list"
    aria-activedescendant="list4-option1" aria-owns="list4"></textarea>

<ul id="list4" role="listbox">
    <li id="list4-option1" role="option">Option 1</li>
    <li id="list4-option2" role="option">Option 2</li>
    <li id="list4-option3" role="option">Option 3</li>
</ul>

<div id="combobox-composite-widget" role="combobox" aria-expanded="true"
    aria-haspopup="menu" aria-autocomplete="list">
  <input id="input-type-text"  type="text" aria-controls="list5"
      aria-activedescendant="list5-option1">
</div>

<ul id="list5" role="listbox">
    <li id="list5-option1" role="option">Option 1</li>
    <li id="list5-option2" role="option">Option 2</li>
    <li id="list5-option3" role="option">Option 3</li>
</ul>

<script>
function testExpectations(t, widgetId, textboxId, listboxId) {
    console.log('testExpectations ' + widgetId);
    var listbox = document.getElementById(listboxId);
    var textbox = document.getElementById(textboxId);
    textbox.focus();

    var widget = document.getElementById(widgetId);

    var axWidget = accessibilityController.accessibleElementById(widgetId);
    var axTextbox = accessibilityController.accessibleElementById(textboxId);
    var axListbox = accessibilityController.accessibleElementById(listboxId);
    var option1 = accessibilityController.accessibleElementById(listboxId + "-option1");
    assert_not_equals(option1, undefined, listboxId + "-option1");
    var option2 = accessibilityController.accessibleElementById(listboxId + "-option2");
    assert_not_equals(option2, undefined, listboxId + "-option2");
    var option3 = accessibilityController.accessibleElementById(listboxId + "-option3");
    assert_not_equals(option3, undefined, listboxId + "-option3");

    assert_false(option1 == null);
    assert_true(axWidget.isExpanded, widgetId + ".isExpanded");
    assert_equals(axWidget.hasPopup, "menu");

    assert_true(option1.isSelectable, listboxId + "-option1.isSelectable");
    assert_true(option2.isSelectable, listboxId + "-option2.isSelectable");
    assert_true(option3.isSelectable, listboxId + "-option3.isSelectable");

    assert_true(axTextbox.isFocused, widgetId + ".isFocused");
    assert_true(option1.isSelected, listboxId + "-option1.isSelected");

    textbox.setAttribute("aria-activedescendant", listboxId + "-option2");

    assert_false(option1.isSelected, listboxId + "-option1.isSelected");
    assert_true(axTextbox.isFocused, widgetId + ".isFocused");
    assert_true(option2.isSelected, listboxId + "-option2.isSelected");

    textbox.setAttribute("aria-activedescendant", listboxId + "-option3");

    assert_false(option2.isSelected, listboxId + "-option2.isSelected");
    assert_true(axTextbox.isFocused, widgetId + ".isFocused");
    assert_true(option3.isSelected, listboxId + "-option3.isSelected");

    textbox.removeAttribute("aria-activedescendant");

    assert_true(axTextbox.isFocused, widgetId + ".isFocused");
    assert_false(option3.isSelected, listboxId + "-option3.isSelected");
    testNext(t);
}

var idsToTest = [
    [ 'contenteditable-combobox', 'contenteditable-combobox', 'list1' ],
    [ 'input-combobox', 'input-combobox', 'list2' ],
    [ 'input-searchbox', 'input-searchbox', 'list3' ],
    [ 'textarea-combobox', 'textarea-combobox', 'list4' ],
    [ 'combobox-composite-widget', 'input-type-text', 'list5' ] ];

function testNext(t) {
    if (idsToTest.length == 0)
        t.done();
    let nextIds = idsToTest.shift();
    t.step(() => { testExpectations(t, nextIds[0], nextIds[1], nextIds[2]) });
}

async_test((t) => {
    testNext(t);
}, 'Changing active descendant correctly sets focused element');
</script>