2 * Copyright 2013 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
8 * Class for testing keyset transitions resulting from use of the left or right
9 * shift key. Keyset transitions are asynchronous, and each test needs to be
10 * broken into subtasks in order to synchronize with keyset updates.
11 * @param {string=} opt_layout Optional name of the initial layout.
12 * @param {string=} opt_unlocked Optional short-name of the lowercase keyset.
13 * @param {string=} opt_locked Optional short-name of the uppercase keyset.
16 function ShiftKeyTester(opt_layout, opt_unlocked, opt_locked) {
17 this.layout = opt_layout || 'qwerty';
18 this.unlocked = opt_unlocked || 'lower';
19 this.locked = opt_locked || 'upper';
23 ShiftKeyTester.prototype = {
25 * Extends the subtask scheduler.
27 __proto__: SubtaskScheduler.prototype,
30 * Adds a subtask for mocking a single key event on a shift key.
31 * @param {string} alignment Indicates if triggering on the left or right
33 * @param {string} keyOp Name of the event.
34 * @param {string} keysetId Expected keyset at the start of the subtask.
35 * @param {boolean=} opt_chording Optional parameter to indicate that the key
36 * event is for a chording operation.
38 keyEvent: function(alignment, keyOp, keysetId, opt_chording) {
41 Debug('Mocking shift key event: alignment = ' + alignment + ', keyOp = ' +
42 keyOp + ', keysetId = ' + keysetId + ', chording = ' +
43 (opt_chording ? true : false));
44 self.alignment = alignment;
45 self.verifyKeyset(keysetId,
46 'Unexpected keyset before shift key event.');
47 var keys = $('keyboard').activeKeyset.querySelectorAll('kb-shift-key');
48 shiftKey = keys[this.alignment == 'left' ? 0 : 1];
49 var mockKeyEvent = {pointerId: 2, isPrimary:true, target: shiftKey};
50 shiftKey[keyOp](mockKeyEvent);
51 // An 'up" event needs to fire a pointer up on the keyboard in order to
52 // handle click counting.
54 $('keyboard').up(mockKeyEvent);
56 shiftKey.out(mockKeyEvent);
58 this.addWaitCondition(fn, keysetId);
63 * Adds a subtask for mocking the typing of a lowercase or uppercase 'A'.
64 * @param {boolean} isUppercase Indicates the case of the character to type.
66 typeCharacterA: function(keysetId) {
69 var isUppercase = keysetId == Keyset.UPPER;
70 Debug('Mock typing ' + (isUppercase ? 'A' : 'a'));
71 self.verifyKeyset(keysetId,
72 'Unexpected keyset for typed character.');
73 mockTypeCharacter(isUppercase ? 'A' : 'a', 0x41,
74 isUppercase ? Modifier.SHIFT : Modifier.NONE);
76 this.addWaitCondition(fn, keysetId);
82 * Retrieves the left or right shift keys. Shift keys come in pairs for upper
83 * and lowercase keyboard layouts respectively.
84 * @param {string} alignment Which of {left, right} shift keys to return.
85 * @return {Object.<string: Object>} a map from keyset to the shift key in it.
87 function getShiftKeys(alignment) {
88 var layout = $('keyboard').layout;
89 var keysets = ['lower', 'upper'];
92 for(var keysetIndex in keysets) {
93 var keysetId = keysets[keysetIndex];
94 // The keyset DOM object which contains a shift key.
95 var keyset = $('keyboard').querySelector('#' + layout + "-" + keysetId);
96 assertTrue(!!keyset, "Cannot find keyset: " + keyset);
97 var shiftKey = keyset.querySelector('kb-shift-key[align="' +
99 assertTrue(!!shiftKey, "Keyset " + keysetId +
100 " does not have a shift key with " + alignment + " alignment");
101 result[keysetId] = shiftKey;
107 * Retrieves the specified modifier key from the system-qwerty layout.
108 * @param {string} modifier Which modifier key to return.
109 * @return {Object} The modifier key.
111 function getModifierKey(modifier) {
112 var keyset = $('keyboard').activeKeyset;
113 assertTrue(!!keyset, 'Cannot find active keyset.');
114 var modifierKey = keyset.querySelector('kb-modifier-key[char="' +
116 assertTrue(!!modifierKey, "Modifier key not found: " + modifierKey);
121 * Tests that a particular shift key has been initialized correctly.
122 * @param {Object} shift The shift key.
124 function checkShiftInitialState(shift) {
125 //Checks that the unlocked case is lower.
126 var unlocked = 'lower';
127 assertEquals(unlocked, shift.lowerCaseKeysetId,
128 "Mismatched lowerCaseKeysetId.");
129 //Checks that the locked case is upper.
130 var locked = 'upper';
131 assertEquals(locked, shift.upperCaseKeysetId,
132 "Mismatched upperCaseKeysetId.");
136 * Asynchronously tests highlighting of the left and right shift keys.
137 * @param {function} testDoneCallBack The function to be called
140 function testShiftHighlightAsync(testDoneCallback) {
141 var tester = new ShiftKeyTester();
143 var checkShiftTap = function(alignment) {
144 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.LOWER);
145 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.UPPER);
146 tester.typeCharacterA(Keyset.UPPER);
147 tester.typeCharacterA(Keyset.LOWER);
149 checkShiftTap(Alignment.LEFT);
150 checkShiftTap(Alignment.RIGHT);
152 tester.scheduleTest('testShiftKeyHighlightAsync', testDoneCallback);
156 * Asynchronously tests initialization of the left and right shift keys.
157 * @param {function} testDoneCallBack The function to be called
160 function testShiftKeyInitAsync(testDoneCallback) {
161 var runTest = function() {
162 var alignments = ['left', 'right'];
163 for (var i in alignments) {
164 var alignment = alignments[i];
165 var shifts = getShiftKeys(alignment);
166 checkShiftInitialState(shifts['lower']);
167 checkShiftInitialState(shifts['upper']);
170 onKeyboardReady('testShiftKeyInitAsync', runTest, testDoneCallback);
174 * Asynchronously tests capitalization on double click of the left and
176 * @param {function} testDoneCallBack The function to be called
179 function testShiftDoubleClickAsync(testDoneCallback) {
180 var tester = new ShiftKeyTester();
182 var checkShiftDoubleClick = function(alignment) {
183 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.LOWER);
184 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.UPPER);
185 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.UPPER);
186 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.UPPER);
188 tester.typeCharacterA(Keyset.UPPER);
189 tester.typeCharacterA(Keyset.UPPER);
191 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.UPPER);
192 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.LOWER);
194 tester.typeCharacterA(Keyset.LOWER);
196 checkShiftDoubleClick(Alignment.LEFT);
197 checkShiftDoubleClick(Alignment.RIGHT);
199 tester.scheduleTest('testShiftDoubleClickAsync', testDoneCallback);
203 * Asynchronously tests capitalization on long press of the left and
205 * @param {function} testDoneCallBack The callback function to be called
208 function testShiftLongPressAsync(testDoneCallback) {
209 var tester = new ShiftKeyTester();
211 var checkShiftLongPress = function(alignment) {
212 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.LOWER);
213 tester.wait(1000, Keyset.UPPER);
214 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.UPPER);
216 tester.typeCharacterA(Keyset.UPPER);
217 tester.typeCharacterA(Keyset.UPPER);
219 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.UPPER);
220 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.LOWER);
222 tester.typeCharacterA(Keyset.LOWER);
224 checkShiftLongPress(Alignment.LEFT);
225 checkShiftLongPress(Alignment.RIGHT);
227 tester.scheduleTest('testShiftLongPressAsync', testDoneCallback);
231 * Asynchronously tests chording on the keyboard.
232 * @param {function} testDoneCallBack The callback function to be called
235 function testShiftChordingAsync(testDoneCallback) {
236 var tester = new ShiftKeyTester();
238 var checkShiftChording = function(alignment) {
239 tester.keyEvent(alignment, EventType.KEY_DOWN, Keyset.LOWER,
240 true /* chording */);
242 tester.typeCharacterA(Keyset.UPPER);
244 tester.wait(1000, Keyset.UPPER);
245 tester.keyEvent(alignment, EventType.KEY_UP, Keyset.UPPER);
247 tester.typeCharacterA(Keyset.LOWER);
249 checkShiftChording('left');
250 checkShiftChording('right');
252 tester.scheduleTest('testShiftChordingAsync', testDoneCallback);
256 * Asynchronously tests modifier keys on the keyboard.
257 * @param {function} testDoneCallBack The callback function to be called
260 function testModifierKeysAsync(testDoneCallback) {
261 var setupWork = function() {
262 $('keyboard').layout = Layout.SYSTEM;
265 var onSystemQwertyLower = function() {
266 assertEquals(Keyset.SYSTEM_LOWER, $('keyboard').activeKeysetId,
269 var ctrl = getModifierKey('Ctrl');
270 var alt = getModifierKey('Alt');
271 var mockEvent = {pointerId: 1};
273 // Test 'ctrl' + 'a'.
274 ctrl.down(mockEvent);
276 mockTypeCharacter('a', 0x41, Modifier.CONTROL);
277 mockTypeCharacter('a', 0x41, Modifier.NONE);
278 // Test 'ctrl' + 'alt' + 'a'.
279 ctrl.down(mockEvent);
283 mockTypeCharacter('a', 0x41, Modifier.CONTROL | Modifier.ALT);
284 mockTypeCharacter('a', 0x41, Modifier.NONE);
285 // Test chording control.
286 ctrl.down(mockEvent);
287 mockTypeCharacter('a', 0x41, Modifier.CONTROL);
288 mockTypeCharacter('a', 0x41, Modifier.CONTROL);
290 mockTypeCharacter('a', 0x41, Modifier.NONE);
291 $('keyboard').layout = 'qwerty';
293 onSystemQwertyLower.waitCondition = {
294 state: 'keysetChanged',
295 value: Keyset.SYSTEM_LOWER
298 var onReset = function() {
299 assertEquals(Keyset.DEFAULT_LOWER, $('keyboard').activeKeysetId,
302 onReset.waitCondition = {
303 state: 'keysetChanged',
304 value: Keyset.DEFAULT_LOWER
307 onKeyboardReady('testModifierKeysAsync', setupWork, testDoneCallback,
308 [onSystemQwertyLower, onReset]);