<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<select id="select" value="Select"></select>
<div id="slider" tabindex="0" role="slider" aria-valuenow="5">Slider</div>
<script>
async_test((t) => {
// Will track all notifications except for 'MarkDirty' -- MarkDirty is a
// catch-all notification that tells the serializer to re-serialize
// a particular node. The number of MarkDirty notifications can
// change as we optimize or fix issues with stale nodes. It doesn't
// make sense to assert test failures based on specific numbers of
// MarkDirty notifications.
window.selectNotificationCount = 0;
window.sliderNotificationCount = 0;
window.globalNotificationCount = 0;
window.select = accessibilityController.accessibleElementById("select");
window.slider = accessibilityController.accessibleElementById("slider");
let expected_element_notifications = new Map([
["Focus", new Map([
["select", 1],
["slider", 1],
])],
["Blur", new Map([
["select", 1],
])],
["ValueChanged", new Map([
["slider", 1],
])],
]);
let expected_global_notifications = new Map([
["Focus", new Map([
["AXRole: AXComboBoxSelect", 1],
["AXRole: AXSlider", 1],
])],
["Blur", new Map([
["AXRole: AXComboBoxSelect", 1],
])],
["ValueChanged", new Map([
["AXRole: AXSlider", 1],
])],
]);
let HandleElementNotification = function(notification, element_key) {
if (notification == 'MarkDirty')
return;
assert_true(expected_element_notifications.has(notification));
let element_map = expected_element_notifications.get(notification);
assert_true(element_map.has(element_key));
let expected_notification_count = element_map.get(element_key);
assert_greater_than(expected_notification_count, 0);
if (expected_notification_count > 1) {
element_map.set(element_key, expected_notification_count - 1);
} else {
element_map.delete(element_key);
if (element_map.size == 0) {
expected_element_notifications.delete(notification);
}
}
};
let HandleGlobalNotification = function(notification, role_key) {
if (notification == 'MarkDirty')
return;
assert_true(expected_global_notifications.has(notification));
let role_map = expected_global_notifications.get(notification);
assert_true(role_map.has(role_key));
let expected_notification_count = role_map.get(role_key);
assert_greater_than(expected_notification_count, 0);
if (expected_notification_count > 1) {
role_map.set(role_key, expected_notification_count - 1);
} else {
role_map.delete(role_key);
if (role_map.size == 0) {
expected_global_notifications.delete(notification);
}
}
};
select.addNotificationListener(t.step_func(function(notification) {
if (notification == 'MarkDirty')
return;
selectNotificationCount++;
console.log("got " + notification + " on select");
HandleElementNotification(notification, "select");
}));
slider.addNotificationListener(t.step_func(function(notification) {
if (notification == 'MarkDirty')
return;
sliderNotificationCount++;
console.log("got " + notification + " on slider");
HandleElementNotification(notification, "slider");
}));
accessibilityController.addNotificationListener(t.step_func(function(element, notification) {
if (notification == 'MarkDirty')
return;
if (element.isEqual(slider) || element.isEqual(select)) {
globalNotificationCount++;
console.log("got " + notification + " on global");
HandleGlobalNotification(notification, element.role);
} else {
console.log('Got unexpected ' + notification + ' notification on ' + element.role);
}
if (expected_element_notifications.size == 0 &&
expected_global_notifications.size === 0) {
assert_equals(selectNotificationCount, 2);
assert_equals(sliderNotificationCount, 2);
assert_equals(globalNotificationCount, 4);
accessibilityController.removeNotificationListener();
select.removeNotificationListener();
slider.removeNotificationListener();
t.done();
}
}));
// This should trigger a "Focus" notification on the select.
document.getElementById("select").focus();
// Wait before focusing the slider, otherwise the select's focus is ingored.
setTimeout(() => {
// This should trigger a "Blur" notification on the select,
// followed by a "Focus" notification on the slider.
document.getElementById("slider").focus();
// This should trigger a "MarkDirty" notification on the select.
document.getElementById("select").setAttribute("aria-invalid", "true");
// This should trigger a "value changed" notification on the slider.
document.getElementById("slider").setAttribute("aria-valuenow", "6");
}, 1);
window.setTimeout(t.step_func_done(() => {
assert_unreached();
}), 100);
}, "This tests that a notification listener on an element only listens to that one element, and that a global notification listener listens to all notifications.");
</script>