blob: 0667cf337180dbd6eea9d60be541edb6cce26bac [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Include test fixture.
GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
/**
* Test fixture.
* @constructor
* @extends {ChromeVoxUnitTestBase}
*/
function CvoxEventWatcherUnitTest() {
ChromeVoxUnitTestBase.call(this);
}
CvoxEventWatcherUnitTest.prototype = {
__proto__: ChromeVoxUnitTestBase.prototype,
/** @override */
isAsync: true,
/** @override */
closureModuleDeps: ChromeVoxUnitTestBase.prototype.closureModuleDeps.concat([
'cvox.ChromeVoxTester',
]),
/** @override */
setUp: function() {
cvox.ChromeVoxTester.setUp(document);
},
/** @override */
tearDown: function() {
cvox.ChromeVoxTester.tearDown(document);
},
/**
* Create mock event object.
* @param {Element} target The event target.
* @param {number=} opt_keyCode The event key code (i.e. 13 for Enter).
* @param {string=} opt_type The event type (i.e. 'keydown' or
* 'focus').
* @param {number=} opt_timeStamp The event timeStamp.
* @return {Event} The mock event.
* @suppress {invalidCasts}
*/
createMockEvent: function(target, opt_keyCode, opt_type, opt_timeStamp) {
var mockEvent = {};
mockEvent.target = target;
if (opt_keyCode) {
mockEvent.keyCode = opt_keyCode;
}
if (opt_type) {
mockEvent.type = opt_type;
}
if (opt_timeStamp) {
mockEvent.timeStamp = opt_timeStamp;
}
return /** @type {Event} */ (mockEvent);
},
/**
* Simulate typing a key into an text field by modifying a given field and
* dispatching a keydown event to ChromeVoxEventWatcher. Allows modifying the
* selection so arrow keypresses can be simulated.
* @param {Element} textField The text field.
* @param {string} newValue The new value for the text field.
* @param {number} newSelStart The new selection start.
* @param {number} newSelEnd The new selection end.
* @param {number} keyCode The key code for the keydown event.
* @return {Element} The modified text field.
*/
changeTextField: function(
textField, newValue, newSelStart, newSelEnd, keyCode) {
textField.value = newValue;
textField.selectionStart = newSelStart;
textField.selectionEnd = newSelEnd;
cvox.ChromeVoxEventWatcher.keyDownEventWatcher(
this.createMockEvent(textField, keyCode, 'keydown'));
return textField;
}
};
TEST_F('CvoxEventWatcherUnitTest', 'ButtonFocusFeedback', function() {
this.loadHtml('<div> <button id="alpha">Alpha</button> </div>');
this.setFocus('alpha');
this.waitForCalm(this.assertSpoken, 'Alpha Button');
});
/**
* Test feedback when focusing links backwards (like shift-tabbing).
*/
TEST_F('CvoxEventWatcherUnitTest', 'FocusLinksBackwards', function() {
this.loadHtml('<div> <p>before</p>' +
'<p><a href="#" id="l1">1</a></p>' +
'<p><a href="#" id="l2">2</a></p>' +
'<p><a href="#" id="l3">3</a></p>' +
'</div>');
this.waitForCalm(this.setFocus, 'l1')
.waitForCalm(this.setFocus, 'l2')
.waitForCalm(this.setFocus, 'l3')
.waitForCalm(this.setFocus, 'l2')
.waitForCalm(this.setFocus, 'l1')
.waitForCalm(this.assertSpoken,
'1 Internal link 2 Internal link 3 Internal link ' +
'2 Internal link 1 Internal link');
});
/**
* Test feedback when an editable text field gets focus.
*/
TEST_F('CvoxEventWatcherUnitTest', 'TextFocusFeedback', function() {
this.loadHtml('<div>' +
'<label for="mytext">Label</label>' +
'<input id="mytext" value="Value" title="Title" />' +
'</div>');
this.setFocus('mytext');
this.waitForCalm(this.assertSpoken, 'Label Value Edit text');
});
/**
* Test feedback when a contenteditable field gets focus.
*/
TEST_F('CvoxEventWatcherUnitTest', 'ContentEditableFocusFeedback', function() {
this.loadHtml('<div>' +
'<label for="mytext">Label</label>' +
'<div id="mytext" contentEditable>This is editable</div>' +
'</div>');
this.setFocus('mytext');
this.waitForCalm(this.assertSpoken, 'Label This is editable Edit text');
});
/**
* Test feedback when an item in an dialog receives focus and then focus
* leaves the dialog.
*/
TEST_F('CvoxEventWatcherUnitTest', 'DialogFeedback', function() {
this.loadHtml('<div>' +
'<button id="show">Show</button>' +
'<div aria-label="compose message" role="dialog">' +
' <button id="ok">OK</button>' +
' <button id="cancel">Cancel</button>' +
'</div>' +
'</div>');
// Enter the dialog by focusing an element inside it.
this.setFocus('ok');
this.waitForCalm(this.assertSpoken,
'Entered dialog compose message Dialog OK Button')
.waitForCalm(function() {
this.setFocus('show')
.setFocus('ok');
})
.waitForCalm(this.assertSpoken, 'OK Button')
.waitForCalm(this.setFocus, 'show')
.waitForCalm(this.assertSpoken, 'Exited dialog. Show Button');
});
/**
* Test feedback when an item in an alert dialog receives focus.
*/
TEST_F('CvoxEventWatcherUnitTest', 'AlertDialogFeedback', function() {
this.loadHtml('<div>' +
'<div role="alertdialog">' +
' <p>Are you sure you want to install Windows?</p>' +
' <button id="yes">Yes</button>' +
' <button id="no">No</button>' +
'</div> </div>');
// Enter the dialog by focusing an element inside it.
this.setFocus('no');
this.waitForCalm(this.assertSpoken,
'Entered dialog ' +
'Are you sure you want to install Windows? Yes Button No Button ' +
'No Button');
});
/**
* Test feedback when focus moves to two different items in a alertdialog
* quickly - make sure the notification that we entered the dialog
* isn't interrupted.
*/
TEST_F('CvoxEventWatcherUnitTest', 'DoubleFocusAlertDialogFeedback',
function() {
this.loadHtml('<div>' +
'<div role="alertdialog">' +
' <p>Are these the droids you\'re looking for?</p>' +
' <button id="yes">Yes</button>' +
' <button id="no">No</button>' +
'</div>' +
'<button id="outside">Outside</button>' +
'</div>');
// Enter the dialog by focusing an element inside it, but then the Jedi
// mind trick quickly changes the default answer.
this.setFocus('yes')
.setFocus('no');
this.waitForCalm(this.assertSpokenList,
this.spokenList()
.categoryFlush('Entered dialog')
.queue('Are these the droids you\'re looking for?')
.queue('Yes')
.queue('Button'))
.waitForCalm(this.setFocus, 'outside')
.waitForCalm(this.assertSpoken, 'Exited dialog. Outside Button');
});
/**
* Test recovery when a dialog box closes and the user sends a tab event.
*/
TEST_F('CvoxEventWatcherUnitTest', 'CloseDialogTabRecovery', function() {
this.loadHtml('<div id="container">' +
'<p id="first">first node</p>' +
'<button id="button">valid button before</button>' +
'<p id="before">valid text before</p>' +
'<p id="dialog">invalid after click</p>' +
'<p id="last">valid text after</p>' +
'</div>');
var first = $('first');
var dialog = $('dialog');
var displayNone = function() {
dialog.style.display = 'none';
};
this.waitForCalm(cvox.ChromeVoxTester.syncToNode, first)
.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'valid button before Button')
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'valid text before')
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'invalid after click')
.waitForCalm(displayNone)
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'valid text after');
});
/**
* Test feedback when a list box with an active descendant receives focus.
*/
TEST_F('CvoxEventWatcherUnitTest', 'ListBoxFeedback', function() {
this.loadHtml('<div>' +
'<p id="before">My listbox</p>' +
'<div id="listbox" role="listbox" tabindex="0"' +
' aria-activedescendant="red">' +
' <div id="red" aria-selected="true" role="option">Red</div>' +
' <div id="yellow" role="option">Yellow</div>' +
' <div id="green" role="option">Green</div>' +
'</div>' +
'<p id="after">After</p>' +
'</div>');
// Focus the listbox.
this.setFocus('listbox');
this.waitForCalm(this.assertSpoken, 'Red List box Selected 1 of 3')
.waitForCalm(function() {
// Set the activeDescendant and fire a keydown event.
// TODO(dmazzoni): replace with a higher-level API that's
// less brittle.
var listbox = $('listbox');
listbox.setAttribute('aria-activeDescendant', 'yellow');
cvox.ChromeVoxEventWatcher.keyDownEventWatcher(/** @type {Event} */ (
{ 'target': listbox,
'type': 'keydown' }));
})
.waitForCalm(this.assertSpoken, 'Yellow 2 of 3');
});
/**
* Test feedback when the items of a list box receive focus.
*/
TEST_F('CvoxEventWatcherUnitTest', 'ListBoxOptionFeedback', function() {
this.loadHtml('<div>' +
'<p id="before">My listbox</p>' +
'<div id="listbox" role="listbox">' +
' <div id="red" tabindex="0" aria-selected="true" role="option">' +
'Red</div>' +
' <div id="yellow" tabindex="-1" role="option">Yellow</div>' +
' <div id="green" tabindex="-1" role="option">Green</div>' +
'</div>' +
'<p id="after">After</p>' +
'</div>');
// Focus the second item.
this.setFocus('yellow');
this.waitForCalm(this.assertSpoken, 'List box Yellow 2 of 3')
.waitForCalm(this.setFocus, 'red')
.waitForCalm(this.assertSpoken, 'Red Selected 1 of 3');
});
/**
* Test feedback when the list box is setting focus in response to arrow
* (or some other) keypress and the user is also using ChromeVox navigation.
*/
TEST_F('CvoxEventWatcherUnitTest', 'ListBoxOptionFeedbackWithFocus', function() {
this.loadHtml('<div>' +
'<p id="before">My listbox</p>' +
'<div id="listbox" role="listbox">' +
' <div id="red" tabindex="0" aria-selected="true" role="option">' +
'Red</div>' +
' <div id="yellow" tabindex="-1" role="option">Yellow</div>' +
' <div id="green" tabindex="-1" role="option">Green</div>' +
' <div id="blue" tabindex="-1" role="option">Blue</div>' +
'</div>' +
'<p id="after">After</p>' +
'</div>');
// Simulate the user using ChromeVox navigation to move forward in the listbox
this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode)
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'List box Red Selected 1 of 4')
.waitForCalm(this.setFocus, 'yellow')
.waitForCalm(this.assertSpoken, 'Yellow 2 of 4')
.waitForCalm(this.setFocus, 'green')
.waitForCalm(this.assertSpoken, 'Green 3 of 4')
.waitForCalm(this.userCommand, 'forward')
.waitForCalm(this.assertSpoken, 'Blue 4 of 4');
});
/**
* Test feedback when interacting with an editable text field.
* The low-level details are tested in editable_text_test.js, this is
* a higher-level test of how that code interacts with the event watcher.
*/
TEST_F('CvoxEventWatcherUnitTest', 'EditableText', function() {
cvox.ChromeVoxEditableTextBase.eventTypingEcho = false;
this.loadHtml('<div>' +
'<button id="before">Before</button>' +
'<label for="input">Query</label>' +
'<input id="input" value="abc">' +
'<p>After</p>' +
'</div>');
var before = $('before');
var input = $('input');
// Focus the button first.
before.focus();
// Then focus the text field.
input.focus();
input.setSelectionRange(3, 3);
this.waitForCalm(this.changeTextField, input, 'abcd', 3, 3, 68) // 'd'
.waitForCalm(this.changeTextField, input, 'abcde', 4, 4, 69) // 'e'
.waitForCalm(this.assertSpokenList,
this.spokenList()
.categoryFlush('Query')
.queue('abc')
.queue('Edit text')
.flush('d')
.flush('e'));
});
/**
* Test feedback when interacting with an editable text field that drives
* an listbox (to form an auto-complete combobox) but doesn't get updated.
* The low-level details are tested in editable_text_test.js, this is
* a higher-level test of how that code interacts with the event watcher.
*/
TEST_F('CvoxEventWatcherUnitTest', 'EditableTextListbox', function() {
this.loadHtml('<div>' +
'<button id="before">Before</button>' +
'<label for="input">Query</label>' +
'<input id="input" value="" role="combobox" aria-autocomplete="list"' +
' aria-activedescendant>' +
'<div role="listbox">' +
' <div id="option1" role="option">First pick</div>' +
' <div id="option2" role="option">Second pick</div>' +
'</div>' +
'<p>After</p>' +
'</div>');
var before = $('before');
var input = $('input');
// Focus the text field.
this.waitForCalm(this.setFocus, 'input')
.waitForCalm(this.assertSpoken, 'Query Combo box Autocompletion list');
this.waitForCalm(function() {
input.setAttribute('aria-activedescendant', 'option1');
this.changeTextField(input, '', 0, 0, 40); // 'down'
})
.waitForCalm(this.assertSpoken, 'First pick 1 of 2');
});
/**
* Test feedback when interacting with an editable text field that drives
* an listbox (to form an auto-complete combobox) and *does* get updated.
* The low-level details are tested in editable_text_test.js, this is
* a higher-level test of how that code interacts with the event watcher.
*/
TEST_F('CvoxEventWatcherUnitTest', 'EditableTextListboxUpdatingInput',
function() {
this.loadHtml('<div>' +
'<button id="before">Before</button>' +
'<label for="input">Query</label>' +
'<input id="input" value="" role="combobox" aria-autocomplete="list"' +
' aria-activedescendant>' +
'<div role="listbox">' +
' <div id="option1" role="option">First pick</div>' +
' <div id="option2" role="option">Second pick</div>' +
'</div>' +
'<p>After</p>' +
'</div>');
var before = $('before');
var input = $('input');
// Focus the text field.
this.waitForCalm(this.setFocus, 'input')
.waitForCalm(this.assertSpoken, 'Query Combo box Autocompletion list');
this.waitForCalm(function() {
input.setAttribute('aria-activedescendant', 'option1');
this.changeTextField(input, 'First pick', 9, 9, 40); // 'down'
})
.waitForCalm(this.assertSpoken, 'First pick');
});
/**
* Tests navigating through a multiline text area.
*/
TEST_F('CvoxEventWatcherUnitTest', 'MultilineNavigation', function() {
this.loadHtml('<div> <textarea id="area">' +
'one' +
'\n\n' +
'two' +
'\n\n' +
'three</textarea>' +
'</div>');
var area = $('area');
function setAreaCursor(pos) {
area.setSelectionRange(pos, pos);
cvox.ChromeVoxEventWatcher.keyDownEventWatcher(/** @type {Event} */ (
{ 'target': area,
'type': 'keydown' }));
}
area.focus();
this.waitForCalm(this.assertSpoken, 'one two three Text area')
.waitForCalm(setAreaCursor, 0)
// The cursor did not move, so don't say anything -- even though we
// did press a key.
.waitForCalm(this.assertSpoken, '')
.waitForCalm(setAreaCursor, 5) // in front on the 'two'
.waitForCalm(this.assertSpoken, 'two')
.waitForCalm(setAreaCursor, 10) // in front of the 'three'
.waitForCalm(this.assertSpoken, 'three')
.waitForCalm(setAreaCursor, 0) // back to the first line
.waitForCalm(this.assertSpoken, 'one')
.waitForCalm(setAreaCursor, 4) // on the first new line
.waitForCalm(this.assertSpoken, 'Blank')
.waitForCalm(setAreaCursor, 5)
.waitForCalm(this.assertSpoken, 'two')
.waitForCalm(setAreaCursor, 9)
.waitForCalm(this.assertSpoken, 'Blank')
.waitForCalm(setAreaCursor, 10)
.waitForCalm(this.assertSpoken, 'three');
});
SYNC_TEST_F('CvoxEventWatcherUnitTest', 'ShouldWaitToProcess', function() {
// The focus event just happened, wait.
assertTrue(
cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(100, 100, 100));
// The focus event just happened, but the first event is old, don't wait.
assertFalse(
cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(100, 0, 100));
// The focus event is old, don't wait.
assertFalse(
cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(0, 0, 100));
});
/**
* Test that no feedback is received for events that fire on elements
* that are hidden (or the descendant of a hidden element).
*/
TEST_F('CvoxEventWatcherUnitTest', 'AriaHiddenFeedback', function() {
this.loadHtml('<div>' +
'<div>' +
' <button id="button1">Button 1</button>' +
' <button id="button2" aria-hidden="true">Button 2</button>' +
'</div>' +
'<div aria-hidden="true">' +
' <h3>Random header</h3>' +
' <div>' +
' <button id="button3">Button 3</button>' +
' </div>' +
' <h3>Random header</h3>' +
'</div>' +
'<div>' +
' <button id="button4">Button 4</button>' +
'</div>' +
'</div>');
this.setFocus('button1')
.waitForCalm(this.assertSpoken, 'Button 1 Button')
.waitForCalm(this.setFocus, 'button2')
.waitForCalm(this.assertSpoken, '')
.waitForCalm(this.setFocus, 'button3')
.waitForCalm(this.assertSpoken, '')
.waitForCalm(this.setFocus, 'button4')
.waitForCalm(this.assertSpoken, 'Button 4 Button');
});
/**
* Test that key down events don't cause excessive value and state announcements
* when arrowing around radiobuttons.
*/
TEST_F('CvoxEventWatcherUnitTest',
'DISABLED_RadioButtonAnnouncements',
function() {
this.loadHtml(
'<input id="radio1" type="radio" aria-label="green" tabindex=0>' +
'<input id="radio2" type="radio" aria-label="blue" tabindex=0>');
function performKeyDown(dir) {
var evt = new KeyboardEvent("keydown", {key: dir});
document.activeElement.dispatchEvent(evt);
};
var radio1 = $('radio1');
radio1.focus();
// TODO(dtseng): Repeated actual spoken text here; this is most certainly a
// test framework bug.
this.waitForCalm(this.assertSpoken, 'green Radio button unselected')
.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
// Moves to next radiobutton.
.waitForCalm(this.assertSpoken,
'blue Radio button selected blue Radio button selected')
.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
// Arrowed beyond end. Should be quiet.
.waitForCalm(this.assertSpoken, '');
this.waitForCalm(performKeyDown, 'ArrowLeft') // left arrow
// Moves back to first radio.
.waitForCalm(this.assertSpoken,
'green Radio button selected green Radio button selected')
.waitForCalm(performKeyDown, 'ArrowLeft') // left arrow
// Arrowed beyond beginning. Should be quiet.
.waitForCalm(this.assertSpoken, '');
});
/**
* Test time widget.
* Disabled because test relies on removed behavior; see crbug.com/520519.
*/
TEST_F('CvoxEventWatcherUnitTest', 'DISABLED_TimeWidget', function() {
this.loadHtml(
'<label for="timewidget">Set alarm for:</label>' +
'<input id="timewidget" type="time" value="12:00">');
var performKeyDown = function(dir) {
var evt = new KeyboardEvent("keydown", {key: dir});
document.activeElement.dispatchEvent(evt);
};
var performKeyUp = function(dir) {
var evt = new KeyboardEvent("keyup", {key: dir});
document.activeElement.dispatchEvent(evt);
};
var timewidget = $('timewidget');
timewidget.focus();
this.waitForCalm(this.assertSpoken,
'Set alarm for: 12:00 Set alarm for: 12 hours 00 minutes PM');
this.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'11 hours');
this.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'10 hours');
this.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
.waitForCalm(performKeyUp, 'ArrowRight') // right arrow
.waitForCalm(performKeyDown, 'ArrowUp') // right arrow
.waitForCalm(performKeyUp, 'ArrowUp') // right arrow
.waitForCalm(this.assertSpoken,
'01 minutes');
this.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'00 minutes');
this.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
.waitForCalm(performKeyUp, 'ArrowRight') // right arrow
.waitForCalm(performKeyDown, 'ArrowUp') // right arrow
.waitForCalm(performKeyUp, 'ArrowUp') // right arrow
.waitForCalm(this.assertSpoken,
'AM');
this.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'PM');
});
/**
* Test date widget.
* Disabled because test relies on removed behavior; see crbug.com/520519.
*/
TEST_F('CvoxEventWatcherUnitTest', 'DISABLED_DateWidget', function() {
this.loadHtml(
'<label for="datewidget">Set birthdate:</label>' +
'<input id="datewidget" type="date" value="1998-09-04"/>');
var performKeyDown = function(dir) {
var evt = new KeyboardEvent("keydown", {key: dir});
document.activeElement.dispatchEvent(evt);
};
var performKeyUp = function(dir) {
var evt = new KeyboardEvent("keyup", {key: dir});
document.activeElement.dispatchEvent(evt);
};
var datewidget = $('datewidget');
datewidget.focus();
this.waitForCalm(this.assertSpoken,
'Set birthdate: 1998-09-04 Date control Set birthdate: September 4 1998')
.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'August')
.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken, 'July')
.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
.waitForCalm(performKeyUp, 'ArrowRight') // right arrow
.waitForCalm(performKeyDown, 'ArrowUp') // right arrow
.waitForCalm(performKeyUp, 'ArrowUp') // right arrow
.waitForCalm(this.assertSpoken, '5')
.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken, '4')
.waitForCalm(performKeyDown, 'ArrowRight') // right arrow
.waitForCalm(performKeyUp, 'ArrowRight') // right arrow
.waitForCalm(performKeyDown, 'ArrowUp') // right arrow
.waitForCalm(performKeyUp, 'ArrowUp') // right arrow
.waitForCalm(this.assertSpoken,
'1999')
.waitForCalm(performKeyDown, 'ArrowDown') // down arrow
.waitForCalm(performKeyUp, 'ArrowDown') // down arrow
.waitForCalm(this.assertSpoken,
'1998');
});
/**
* Test that ChromeVox speaks the correct state when a focused control
* changes as the result of a key up, not just key down.
*/
TEST_F('CvoxEventWatcherUnitTest', 'ToggleOnKeyUp', function() {
this.loadHtml('<div>' +
'<div tabIndex=0 id="pressable" role="button" aria-pressed="false">' +
'Toggle' +
'</div>' +
'</div>');
// Focus on the button.
this.setFocus('pressable');
this.waitForCalm(this.assertSpoken, 'Toggle Button Not pressed');
function keyupSpace() {
var evt = document.createEvent('KeyboardEvent');
evt.initKeyboardEvent(
'keyup', true, true, window, ' ', 0, false, false, false, false);
document.activeElement.dispatchEvent(evt);
}
function keyupSpaceAndMarkPressed() {
keyupSpace();
$('pressable').setAttribute('aria-pressed', 'true');
};
function keyupSpaceAndMarkNotPressed() {
keyupSpace();
$('pressable').setAttribute('aria-pressed', 'false');
};
this.waitForCalm(keyupSpaceAndMarkPressed)
.waitForCalm(this.assertSpoken, 'Pressed')
.waitForCalm(keyupSpaceAndMarkNotPressed)
.waitForCalm(this.assertSpoken, 'Not pressed');
});
/**
* Exiting dialog message should not interrupt a live region.
*/
TEST_F('CvoxEventWatcherUnitTest', 'DISABLED_ExitDialogWithLiveRegion', function() {
this.loadHtml(
'<div role="dialog" aria-label="MyAlert">' +
' <h1>Heading</h1>' +
' <button id="initial">Initial focus</button>' +
'</div>' +
'<div>' +
' <button id="final">Final focus</button>' +
'</div>' +
'<div id="live" aria-live="polite"></div>');
// Focus on the button in the dialog.
this.setFocus('initial');
this.waitForCalm(this.assertSpoken,
'Entered dialog MyAlert Dialog Initial focus Button')
.waitForCalm(function() {
$('live').innerText = 'Live region changed';
})
.waitForCalm(function() {
this.setFocus('final');
})
.waitForCalm(function() {
var ulist = cvox.ChromeVoxTester.testTts().getSpeechQueueOutput();
assertEquals('Live region changed', ulist[0]);
assertEquals('Exited dialog.', ulist[1]);
assertEquals('Final focus', ulist[2]);
assertEquals('Button', ulist[3]);
});
});