// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
//
//
///
///
///
//
module WinJSTests {
"use strict";
var COUNT = 100,
ITEMS_PER_GROUP = 10;
var ListView = WinJS.UI.ListView;
var testRootEl;
var origMaxTimePerCreateContainers;
var origChunkSize;
function setupListview(element, layoutName, useGroups = false) {
var charCodeA = "A".charCodeAt(0),
myData = [];
for (var i = 0; i < COUNT; ++i) {
myData.push({ title: String.fromCharCode(charCodeA + Math.floor(i / ITEMS_PER_GROUP)) + " Tile" + i });
}
var options: any = {
layout: new WinJS.UI[layoutName](),
itemDataSource: Helper.ItemsManager.simpleSynchronousArrayDataSource(myData),
itemTemplate: Helper.ListView.createRenderer("simpleTemplate"),
selectionMode: "none"
};
if (useGroups) {
options.itemDataSource = WinJS.UI.computeDataSourceGroups(options.itemDataSource,
function (item) {
return item.data.title.charAt(0);
},
function (item) {
return { title: item.data.title.charAt(0) };
}
);
options.groupDataSource = options.itemDataSource.groups;
options.groupHeaderTemplate = Helper.ListView.createRenderer("smallGroupHeaderTemplate");
}
return new ListView(element, options);
}
function waitForAria(listView) {
return new WinJS.Promise(function (c, e, p) {
function waitForAccessibilityComplete_handler() {
listView.removeEventListener("accessibilityannotationcomplete", waitForAccessibilityComplete_handler, false);
c();
}
listView.addEventListener("accessibilityannotationcomplete", waitForAccessibilityComplete_handler, false);
});
}
function getItem(listview, index) {
return listview.elementFromIndex(index);
}
function getHeader(listview, groupIndex) {
// Test to see if we are in old layouts or new layouts
return listview._groups.group(groupIndex).elements ? listview._groups.group(groupIndex).elements.header : listview._groups.group(groupIndex).header;
}
function getAttribute(listview, index, attribute) {
return listview.elementFromIndex(index).getAttribute(attribute);
}
function checkFlow(from, to) {
LiveUnit.Assert.areEqual(to.id, from.getAttribute("aria-flowto"), "Incorrect id for aria-flowto attribute");
LiveUnit.Assert.areEqual(from.id, to.getAttribute("x-ms-aria-flowfrom"), "Incorrect id for x-ms-aria-flowfrom attribute");
}
function checkTile(listview, index, role) {
var tile = listview.elementFromIndex(index);
LiveUnit.Assert.areEqual(tile.getAttribute("role"), role);
LiveUnit.Assert.areEqual(parseInt(tile.getAttribute("aria-setsize"), 10), COUNT);
LiveUnit.Assert.areEqual(parseInt(tile.getAttribute("aria-posinset"), 10), index + 1);
}
function checkGroupFlow(listView, groupIndex, groupStart, realizedGroupLast) {
var realizedStart = listView._view.begin,
realizedLast = listView._view.end - 1,
firstVisibleGroupIndex = listView._groups.groupFromItem(listView.indexOfFirstVisible),
// First realized item in the group
realizedGroupStart = Math.max(groupStart, realizedStart),
firstItem = getItem(listView, realizedGroupStart),
firstVisibleItem = getItem(listView, listView.indexOfFirstVisible),
lastVisibleItem = getItem(listView, listView.indexOfLastVisible),
header = getHeader(listView, groupIndex),
i;
// Check flow for the start marker, the header, and the first item
checkFlow(header, firstItem);
if (groupStart <= realizedStart) {
// This is the first realized group
LiveUnit.Assert.areEqual(listView._ariaStartMarker.id, header.getAttribute("x-ms-aria-flowfrom"), "The group's header should flow from the start marker");
}
if (groupIndex === firstVisibleGroupIndex) {
// This is the first visible group
if (groupStart === listView.indexOfFirstVisible) {
// Its first item is visible so flow to its header
LiveUnit.Assert.areEqual(header.id, listView._ariaStartMarker.getAttribute("aria-flowto"), "The start marker should flow to the group's header");
} else {
// Its first item is not visible so flow to its first visible item
LiveUnit.Assert.areEqual(firstVisibleItem.id, listView._ariaStartMarker.getAttribute("aria-flowto"), "The start marker should flow to the group's first item");
}
}
// Check flow between the items (exclude the last item -- it'll be checked below)
for (i = realizedGroupStart; i <= realizedGroupLast - 1; i++) {
checkFlow(getItem(listView, i), getItem(listView, i + 1));
}
// Check flow for the last item and the end marker
if (listView.indexOfLastVisible >= realizedGroupStart && listView.indexOfLastVisible <= realizedGroupLast) {
// This group contains the last visible item
LiveUnit.Assert.areEqual(lastVisibleItem.id, listView._ariaEndMarker.getAttribute("x-ms-aria-flowfrom"), "The end marker should flow from the last visible item");
}
if (realizedGroupLast < realizedLast) {
// This isn't the last group
checkFlow(getItem(listView, realizedGroupLast), getHeader(listView, groupIndex + 1));
} else {
// This is the last group
LiveUnit.Assert.areEqual(listView._ariaEndMarker.id, getItem(listView, realizedGroupLast).getAttribute("aria-flowto"), "The last realized item should flow to the end marker");
}
}
function checkListViewFlow(listView) {
var groups = listView._groups,
groupIndex = groups.groupFromItem(listView._view.begin),
realizedLast = listView._view.end - 1,
lastGroupIndex = groups.groupFromItem(realizedLast),
realizedGroupLast;
for (; groupIndex <= lastGroupIndex; groupIndex++) {
if (groupIndex < lastGroupIndex) {
realizedGroupLast = groups.group(groupIndex + 1).startIndex - 1;
} else {
realizedGroupLast = realizedLast;
}
checkGroupFlow(listView, groupIndex, groups.group(groupIndex).startIndex, realizedGroupLast);
}
}
function checkAttributesNoGroups(listView, firstRealized, lastRealized, listRole, itemRole) {
LiveUnit.Assert.areEqual(listView.element.getAttribute("role"), listRole);
// Start marker should flow to the first visible item
LiveUnit.Assert.areEqual(getItem(listView, 0).id, listView._ariaStartMarker.getAttribute("aria-flowto"), "The start marker should flow to the first visible item");
// Start marker should flow from the first realized item
LiveUnit.Assert.areEqual(listView._ariaStartMarker.id, getItem(listView, firstRealized).getAttribute("x-ms-aria-flowfrom"), "The first realized item should flow from the start marker");
checkTile(listView, 0, itemRole);
checkTile(listView, 1, itemRole);
checkTile(listView, 2, itemRole);
// Items should flow to/from adjacent items
checkFlow(getItem(listView, 0), getItem(listView, 1));
checkFlow(getItem(listView, 1), getItem(listView, 2));
checkFlow(getItem(listView, 2), getItem(listView, 3));
// Last realized item should flow to the end marker
LiveUnit.Assert.areEqual(listView._ariaEndMarker.id, getItem(listView, lastRealized).getAttribute("aria-flowto"), "The last realized item should flow to the end marker");
// Last visible item should flow from the end marker
LiveUnit.Assert.areEqual(getItem(listView, listView.indexOfLastVisible).id, listView._ariaEndMarker.getAttribute("x-ms-aria-flowfrom"), "The last visible item should flow from the end marker");
}
export class AriaTests {
// This is the setup function that will be called at the beginning of each test function.
setUp() {
LiveUnit.LoggingCore.logComment("In setup");
origMaxTimePerCreateContainers = WinJS.UI._VirtualizeContentsView._maxTimePerCreateContainers;
origChunkSize = WinJS.UI._VirtualizeContentsView._chunkSize;
testRootEl = document.createElement("div");
testRootEl.className = "file-listview-css";
var newNode = document.createElement("div");
newNode.id = "AriaTests";
newNode.innerHTML =
"" +
"" +
"" +
"";
testRootEl.appendChild(newNode);
document.body.appendChild(testRootEl);
}
tearDown() {
LiveUnit.LoggingCore.logComment("In tearDown");
WinJS.UI._VirtualizeContentsView._maxTimePerCreateContainers = origMaxTimePerCreateContainers;
WinJS.UI._VirtualizeContentsView._chunkSize = origChunkSize;
WinJS.Utilities.disposeSubTree(testRootEl);
document.body.removeChild(testRootEl);
}
// Verifies that aria-selected attribute change notifications are properly ignored
// after the ListView has been disposed.
// Regression test for WinBlue#395099
testItemPropertyChangeAfterDispose = function (complete) {
Helper.initUnhandledErrors();
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, "ListLayout");
Helper.ListView.waitForReady(listView)().then(function () {
listView.selection.add(0);
listView.dispose();
return WinJS.Utilities.Scheduler.schedulePromiseIdle();
}).done(function () {
Helper.validateUnhandledErrors();
complete();
});
};
// Verifies that when there isn't enough time to create all of the containers synchronously,
// the ARIA attributes still get set.
// Regression test for WinBlue#197944
testAriaWithAsyncContainerCreation = function (complete) {
WinJS.UI._VirtualizeContentsView._maxTimePerCreateContainers = 0;
WinJS.UI._VirtualizeContentsView._chunkSize = 1;
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, "ListLayout");
LiveUnit.Assert.isTrue(listView.selectionMode.toString() === "none");
waitForAria(listView).then(function () {
var lastRealized = listView._view.end - 1;
checkAttributesNoGroups(listView, 0, lastRealized, "listbox", "option");
complete();
});
};
// Verifies that the ARIA worker doesn't throw an exception when the ListView is hidden.
// Regression test for WinBlue#238241.
testAriaWhenListViewIsHidden = function (complete) {
var myData = [];
for (var i = 0; i < COUNT; ++i) {
myData.push({ title: " Tile" + i });
}
var cancelingLayout = {
initialize: function () { /* Required method of ILayout2 */ },
layout: function () {
// Simulates what a layout does when the ListView is hidden
return WinJS.Promise.cancel;
}
};
var element = document.getElementById("ariaTestList");
var listView = new ListView(element, {
layout: cancelingLayout,
itemDataSource: new WinJS.Binding.List(myData).dataSource,
itemTemplate: Helper.ListView.createRenderer("simpleTemplate"),
selectionMode: "none"
});
Helper.ListView.waitForReady(listView)().then(function () {
// If the ARIA work completes without throwing an exception
// then complete the test successfully.
listView._view.deferTimeout.then(function () {
complete();
});
});
};
testUpdateAriaMarkersWhenRealizedRangeHasHoles = function (complete) {
var myData = [];
var startMarker;
var endMarker;
var indexOfFirstVisible;
var indexOfLastVisible;
function resolveToElement(indexOrElement) {
return +indexOrElement === indexOrElement ?
listView.elementFromIndex(indexOrElement) :
indexOrElement;
}
function verifyMarkers(description, options) {
var defaultOptions = {
indexOfFirstVisible: indexOfFirstVisible,
indexOfLastVisible: indexOfLastVisible,
nullIndices: []
};
options = WinJS.Utilities._merge(defaultOptions, options);
// Required options
var startMarkerFlowsTo = resolveToElement(options.startMarkerFlowsTo);
var endMarkerFlowsFrom = resolveToElement(options.endMarkerFlowsFrom);
// Optional options
var firstVisible = options.indexOfFirstVisible;
var lastVisible = options.indexOfLastVisible;
var nullIndices = options.nullIndices;
var items = listView._view.items;
function withItemAtOverridden(callback) {
var origItemAt = items.itemAt;
items.itemAt = function (index) {
if (nullIndices.indexOf(index) !== -1) {
return null;
} else {
return origItemAt.apply(items, arguments);
}
};
callback();
items.itemAt = origItemAt;
}
// Reset state for this test
startMarker.removeAttribute("aria-flowto");
endMarker.removeAttribute("x-ms-aria-flowfrom");
// Ask view to update state of markers
withItemAtOverridden(function () {
listView._view._updateAriaMarkers(false, firstVisible, lastVisible);
});
// Verify flow-to/from on markers
LiveUnit.Assert.areEqual(startMarkerFlowsTo.id, startMarker.getAttribute("aria-flowto"),
description + ": start marker has incorrect aria-flowto");
LiveUnit.Assert.areEqual(endMarkerFlowsFrom.id, endMarker.getAttribute("x-ms-aria-flowfrom"),
description + ": end marker has incorrect x-ms-aria-flowfrom");
}
for (var i = 0; i < COUNT; ++i) {
myData.push({ title: " Tile" + i });
}
var element = document.getElementById("ariaTestList");
var listView = new ListView(element, {
itemDataSource: new WinJS.Binding.List(myData).dataSource,
itemTemplate: Helper.ListView.createRenderer("simpleTemplate"),
selectionMode: "none"
});
Helper.ListView.waitForReady(listView)().then(function () {
startMarker = listView._ariaStartMarker;
endMarker = listView._ariaEndMarker;
indexOfFirstVisible = listView.indexOfFirstVisible;
indexOfLastVisible = listView.indexOfLastVisible;
verifyMarkers("Verifying with no holes in realized range", {
startMarkerFlowsTo: indexOfFirstVisible,
endMarkerFlowsFrom: indexOfLastVisible
});
verifyMarkers("Verifying with hole at first visible index", {
nullIndices: [indexOfFirstVisible],
startMarkerFlowsTo: endMarker,
endMarkerFlowsFrom: startMarker
});
verifyMarkers("Verifying with hole at last visible index", {
nullIndices: [indexOfLastVisible],
startMarkerFlowsTo: indexOfFirstVisible,
endMarkerFlowsFrom: indexOfLastVisible - 1
});
verifyMarkers("Verifying with holes at first and last visible indices", {
nullIndices: [indexOfFirstVisible, indexOfLastVisible],
startMarkerFlowsTo: endMarker,
endMarkerFlowsFrom: startMarker
});
verifyMarkers("Verifying with holes at back of realized range", {
nullIndices: [indexOfLastVisible, indexOfLastVisible - 1, indexOfLastVisible - 2, indexOfLastVisible - 3],
startMarkerFlowsTo: indexOfFirstVisible,
endMarkerFlowsFrom: indexOfLastVisible - 4
});
verifyMarkers("Verifying with indexOfFirstVisible > indexOfLastVisible", {
indexOfFirstVisible: 1,
indexOfLastVisible: 0,
startMarkerFlowsTo: endMarker,
endMarkerFlowsFrom: startMarker
});
verifyMarkers("Verifying with indexOfFirstVisible = indexOfLastVisible = -1", {
indexOfFirstVisible: -1,
indexOfLastVisible: -1,
startMarkerFlowsTo: endMarker,
endMarkerFlowsFrom: startMarker
});
complete();
});
};
testAriaRoleInInvocableGroupHeaders = function (complete) {
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, "GridLayout", true)
waitForAria(listView).then(function () {
// Headers A - G should be realized
var headers: any = listView.element.querySelectorAll(".win-groupheader");
LiveUnit.Assert.areEqual("A", headers[0].textContent.trim());
LiveUnit.Assert.areEqual("link", headers[0].getAttribute("role"));
LiveUnit.Assert.areEqual("G", headers[6].textContent.trim());
LiveUnit.Assert.areEqual("link", headers[6].getAttribute("role"));
listView.scrollPosition = 10000;
return waitForAria(listView);
}).done(function () {
// Header J (the last header) should be realized
var headers: any = listView.element.querySelectorAll(".win-groupheader");
// Since annotationcomplete event may get fired before previous
// headers were unrealized, we do not know for sure which index
// header J is in.
for (var i = 0, len = headers.length; i < len; i++) {
if (headers[i].textContent.trim() === "J") {
LiveUnit.Assert.areEqual("link", headers[i].getAttribute("role"));
complete();
return;
}
}
LiveUnit.Assert.fail("Couldn't find J header");
});
};
testAriaRoleInNonInvocableGroupHeaders = function (complete) {
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, "GridLayout", true)
listView.groupHeaderTapBehavior = WinJS.UI.GroupHeaderTapBehavior.none;
waitForAria(listView).then(function () {
// Headers A - G should be realized
var headers: any = listView.element.querySelectorAll(".win-groupheader");
LiveUnit.Assert.areEqual("A", headers[0].textContent.trim());
LiveUnit.Assert.areEqual("separator", headers[0].getAttribute("role"));
LiveUnit.Assert.areEqual("G", headers[6].textContent.trim());
LiveUnit.Assert.areEqual("separator", headers[6].getAttribute("role"));
listView.scrollPosition = 10000;
return waitForAria(listView);
}).done(function () {
// Header J (the last header) should be realized
var headers: any = listView.element.querySelectorAll(".win-groupheader");
// Since annotationcomplete event may get fired before previous
// headers were unrealized, we do not know for sure which index
// header J is in.
for (var i = 0, len = headers.length; i < len; i++) {
if (headers[i].textContent.trim() === "J") {
LiveUnit.Assert.areEqual("separator", headers[i].getAttribute("role"));
complete();
return;
}
}
LiveUnit.Assert.fail("Couldn't find J header");
});
};
}
function generate(testName, testFn) {
["GridLayout"].forEach(function (layoutName) {
AriaTests.prototype[testName + "_" + layoutName] = function (complete) {
testFn(complete, layoutName);
}
});
}
generate("testBrowse", function (complete, layoutName) {
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, layoutName);
LiveUnit.Assert.isTrue(listView.selectionMode.toString() === "none");
waitForAria(listView).then(function () {
var lastRealized = listView._view.end - 1;
checkAttributesNoGroups(listView, 0, lastRealized, "listbox", "option");
complete();
});
});
function generateGroupAttributes(layoutName) {
AriaTests.prototype["testGroupAttributes" + layoutName] = function (complete) {
var element = document.getElementById("smallAriaTestList");
var listView = setupListview(element, layoutName, true);
waitForAria(listView).then(function () {
LiveUnit.LoggingCore.logComment("Testing with first visible group's first item visible");
LiveUnit.Assert.isTrue(listView.indexOfFirstVisible % ITEMS_PER_GROUP === 0, "The first visible group's first item should be visible");
checkListViewFlow(listView);
listView.indexOfFirstVisible = 53;
return waitForAria(listView);
}).then(function () {
LiveUnit.LoggingCore.logComment("Testing with first visible group's first item not visible");
LiveUnit.Assert.isTrue(listView.indexOfFirstVisible % ITEMS_PER_GROUP !== 0, "The first visible group's first item should not be visible");
checkListViewFlow(listView);
complete();
});
};
};
generateGroupAttributes("GridLayout");
// Verify that in an empty ListView, the start marker flows to the end marker
generate("testEmptyListView", function (complete, layoutName) {
var element = document.getElementById("ariaTestList");
var listView = new ListView(element, {
layout: new WinJS.UI[layoutName](),
itemDataSource: new WinJS.Binding.List([]).dataSource,
itemTemplate: Helper.ListView.createRenderer("simpleTemplate")
});
waitForAria(listView).then(function () {
var startMarker = listView._ariaStartMarker,
endMarker = listView._ariaEndMarker;
LiveUnit.Assert.areEqual(endMarker.id, startMarker.getAttribute("aria-flowto"), "The start marker should flowto the end marker");
LiveUnit.Assert.areEqual(startMarker.id, endMarker.getAttribute("x-ms-aria-flowfrom"), "The end marker should flowfrom the start marker");
complete();
});
});
generate("testaccessibilityEventForEmptyList", function (complete, layoutName) {
var element = document.getElementById("ariaTestList");
var listView = new WinJS.UI.ListView(element, {
itemDataSource: new WinJS.Binding.List([]).dataSource,
itemTemplate: Helper.ListView.createRenderer("simpleTemplate"),
layout: new WinJS.UI[layoutName]()
});
listView.addEventListener("accessibilityannotationcomplete", function (ev) {
LiveUnit.Assert.areEqual(-1, ev.detail.firstIndex);
LiveUnit.Assert.areEqual(-1, ev.detail.lastIndex);
complete();
});
});
generate("testaccessibilityEventForListWithItems", function (complete, layoutName) {
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, layoutName);
listView.addEventListener("accessibilityannotationcomplete", function (ev) {
LiveUnit.Assert.areEqual(0, ev.detail.firstIndex);
LiveUnit.Assert.areEqual(99, ev.detail.lastIndex);
complete();
});
});
function generateUIASelect(layoutName) {
AriaTests.prototype["testUIASelect" + layoutName] = function (complete) {
function blockSelection(eventObject) {
eventObject.preventDefault();
}
function test() {
var prevSelection;
function verifySelection(expectedSelection) {
prevSelection = expectedSelection;
LiveUnit.Assert.areEqual(expectedSelection.length, listView.selection.count(),
"ListView's selection manager has the wrong number of items selected");
Helper.ListView.elementsEqual(expectedSelection, listView.selection.getIndices());
for (var i = 0; i < 2; i++) {
var item = listView.elementFromIndex(i);
var expectedSelected = (expectedSelection.indexOf(i) !== -1);
LiveUnit.Assert.areEqual(expectedSelected, WinJS.Utilities.hasClass(item.parentNode, WinJS.UI._selectedClass),
"Item " + i + ": win-item's selected class is in the wrong state");
LiveUnit.Assert.areEqual(expectedSelected, item.getAttribute("aria-selected") === "true",
"Item " + i + ": aria-selected is incorrect");
LiveUnit.Assert.areEqual(expectedSelected, listView.selection._isIncluded(i),
"Item " + i + ": ListView's selection manager is incorrect");
}
}
function verifySelectionDidntChange() {
verifySelection(prevSelection);
}
var element = document.getElementById("ariaTestList");
var listView = setupListview(element, layoutName);
listView.selectionMode = WinJS.UI.SelectionMode.single;
var selectionChanges = 0;
listView.addEventListener("selectionchanged", function (eventObject) {
selectionChanges++;
}, false);
var firstTile, secondTile;
return Helper.ListView.waitForReady(listView)().
then(function () {
verifySelection([]);
firstTile = listView.elementFromIndex(0);
secondTile = listView.elementFromIndex(1);
firstTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
firstTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([]);
firstTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([1]);
// Simulate UIA SelectionItem.Select
firstTile.setAttribute("aria-selected", "true");
secondTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
// Simulate UIA SelectionItem.Select with blocked selection
listView.addEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "false");
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelectionDidntChange();
// Simulate UIA SelectionItem.Select
listView.removeEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "false");
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([1]);
// Simulate UIA SelectionItem.Select with blocked selection
listView.addEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "true");
secondTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelectionDidntChange();
listView.removeEventListener("selectionchanging", blockSelection, false);
secondTile.removeAttribute("aria-selected");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([]);
listView.selectionMode = WinJS.UI.SelectionMode.multi;
firstTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0, 1]);
secondTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
listView.addEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "false");
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelectionDidntChange();
// Simulate UIA SelectionItem.Select
listView.removeEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "false");
secondTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([1]);
// Simulate UIA SelectionItem.Select with blocked selection
listView.addEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "true");
secondTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelectionDidntChange();
// Simulate UIA SelectionItem.Select
listView.removeEventListener("selectionchanging", blockSelection, false);
firstTile.setAttribute("aria-selected", "true");
secondTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([0]);
firstTile.setAttribute("aria-selected", "false");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelection([]);
LiveUnit.Assert.areEqual(13, selectionChanges);
listView.selectionMode = WinJS.UI.SelectionMode.none;
firstTile.setAttribute("aria-selected", "true");
return WinJS.Promise.timeout();
}).
then(function () {
verifySelectionDidntChange();
LiveUnit.Assert.areEqual(13, selectionChanges);
});
}
test().done(complete);
};
};
if (!WinJS.Utilities.isPhone) {
generateUIASelect("GridLayout");
// Verify that the list and item roles are updated appropriately when switching from
// a non-static mode to a static mode and vice versa.
generate("testChangingRoles", function (complete, layoutName) {
function checkRoles(listRole, itemRole, context) {
LiveUnit.Assert.areEqual(listRole, element.getAttribute("role"), "Incorrect list role " + context);
LiveUnit.Assert.areEqual(itemRole, getAttribute(listView, 0, "role"), "Incorrect item role " + context);
LiveUnit.Assert.areEqual(itemRole, getAttribute(listView, 1, "role"), "Incorrect item role " + context);
LiveUnit.Assert.areEqual(itemRole, getAttribute(listView, 2, "role"), "Incorrect item role " + context);
}
var element = document.getElementById("ariaTestList"),
listView = setupListview(element, layoutName);
var tests = [
function () {
setTimeout(function () {
// Validate the roles in the initial mode (non-static)
LiveUnit.Assert.areEqual("none", listView.selectionMode);
LiveUnit.Assert.areEqual("invokeOnly", listView.tapBehavior);
checkRoles("listbox", "option", "in the initial non-static mode");
// Switch to static mode and validate the roles
listView.tapBehavior = WinJS.UI.TapBehavior.none;
checkRoles("list", "listitem", "after switching to static mode");
// Switch to a non-static mode and validate the roles
listView.selectionMode = WinJS.UI.SelectionMode.single;
checkRoles("listbox", "option", "after switching to a non-static mode");
complete();
}, 1000);
}
];
Helper.ListView.runTests(listView, tests);
});
}
}
// register the object as a test class by passing in the name
LiveUnit.registerTestClass("WinJSTests.AriaTests");