<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/run-after-layout-and-paint.js"></script>
</head>
<body>

<select multiple id="menulist">
  <option selected>One</option>
  <option>Two</option>
  <option>Three</option>
  <option>Four</option>
</select>

<p id="description"></p>

<script>
// Wait until layout has settled to avoid notification spam.
async_test_after_layout_and_paint((testCase) => {
    const expectedNotifications = [
        'ActiveDescendantChanged',
        'Focus',
        'SelectedChildrenChanged',
        'SelectedChildrenChanged',
        'ActiveDescendantChanged',
        'SelectedChildrenChanged',
        'ActiveDescendantChanged',
    ];
    let notificationReceivedIndex = 0;

    assert_own_property(window, 'accessibilityController');

    var menulist = document.getElementById("menulist");
    menulist.focus();
    window.accessibleMenulist = accessibilityController.focusedElement;
    window.accessibleOne = accessibleMenulist.childAtIndex(0);
    window.accessibleTwo = accessibleMenulist.childAtIndex(1);
    window.accessibleThree = accessibleMenulist.childAtIndex(2);

    function listListener(notification) {
        assert_less_than(notificationReceivedIndex, expectedNotifications.length);
        assert_equals(notification, expectedNotifications[notificationReceivedIndex],
                      `Notification ${notificationReceivedIndex}`);
        ++notificationReceivedIndex;
    }
    accessibleMenulist.addNotificationListener(listListener);

    assert_true(accessibleOne.isSelected);
    assert_true(accessibleOne.isSelectedOptionActive);
    assert_false(accessibleTwo.isSelected);
    assert_false(accessibleTwo.isSelectedOptionActive);
    assert_false(accessibleThree.isSelected);
    assert_false(accessibleThree.isSelectedOptionActive);

    // Change the selected index by simulating a down arrow keydown event.
    eventSender.keyDown('ArrowDown', []);

    assert_false(accessibleOne.isSelected);
    assert_false(accessibleOne.isSelectedOptionActive);
    assert_true(accessibleTwo.isSelected);
    assert_true(accessibleTwo.isSelectedOptionActive);
    assert_false(accessibleThree.isSelected);
    assert_false(accessibleThree.isSelectedOptionActive);

    // Extend the selection by simulating a Shift + Down Arrow keydown event.
    eventSender.keyDown('ArrowDown', ['shiftKey']);

    assert_false(accessibleOne.isSelected);
    assert_false(accessibleOne.isSelectedOptionActive);
    assert_true(accessibleTwo.isSelected);
    assert_false(accessibleTwo.isSelectedOptionActive);
    assert_true(accessibleThree.isSelected);
    assert_true(accessibleThree.isSelectedOptionActive);

    // Make the test finish quickly whether we get the notification or not.
    window.setTimeout(testCase.step_func(() => {
        if (window.accessibilityController)
            accessibleMenulist.removeNotificationListener();
        assert_equals(notificationReceivedIndex, expectedNotifications.length,
                      'All notifications received');
        testCase.done();
    }), 10);
}, 'Navigating in a multiselect list updates selection and the active selected option and sends a notification');

</script>
</body>
</html>
