]> git.proxmox.com Git - mirror_novnc.git/blame - tests/test.keyboard.js
feat: add French localization strings
[mirror_novnc.git] / tests / test.keyboard.js
CommitLineData
2b5f94fa 1const expect = chai.expect;
f00b6fb6 2
c1e2785f 3import Keyboard from '../core/input/keyboard.js';
099eb856 4
2c5491e1 5describe('Key Event Handling', function () {
f00b6fb6 6 "use strict";
f00b6fb6 7
f7363fd2
PO
8 // The real KeyboardEvent constructor might not work everywhere we
9 // want to run these tests
10 function keyevent(typeArg, KeyboardEventInit) {
2b5f94fa
JD
11 const e = { type: typeArg };
12 for (let key in KeyboardEventInit) {
f7363fd2
PO
13 e[key] = KeyboardEventInit[key];
14 }
15 e.stopPropagation = sinon.spy();
16 e.preventDefault = sinon.spy();
17 return e;
8727f598 18 }
f00b6fb6 19
2c5491e1
PO
20 describe('Decode Keyboard Events', function () {
21 it('should decode keydown events', function (done) {
2b5f94fa 22 const kbd = new Keyboard(document);
651c23ec 23 kbd.onkeyevent = (keysym, code, down) => {
f7363fd2
PO
24 expect(keysym).to.be.equal(0x61);
25 expect(code).to.be.equal('KeyA');
26 expect(down).to.be.equal(true);
27 done();
747b4623 28 };
f7363fd2
PO
29 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
30 });
2c5491e1 31 it('should decode keyup events', function (done) {
2b5f94fa
JD
32 let calls = 0;
33 const kbd = new Keyboard(document);
651c23ec 34 kbd.onkeyevent = (keysym, code, down) => {
f7363fd2
PO
35 expect(keysym).to.be.equal(0x61);
36 expect(code).to.be.equal('KeyA');
37 if (calls++ === 1) {
38 expect(down).to.be.equal(false);
39 done();
40 }
747b4623 41 };
f7363fd2
PO
42 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
43 kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
44 });
f00b6fb6 45 });
46
2c5491e1
PO
47 describe('Fake keyup', function () {
48 it('should fake keyup events for virtual keyboards', function (done) {
2b5f94fa
JD
49 let count = 0;
50 const kbd = new Keyboard(document);
651c23ec 51 kbd.onkeyevent = (keysym, code, down) => {
9e99ce12
PO
52 switch (count++) {
53 case 0:
54 expect(keysym).to.be.equal(0x61);
55 expect(code).to.be.equal('Unidentified');
56 expect(down).to.be.equal(true);
57 break;
58 case 1:
59 expect(keysym).to.be.equal(0x61);
60 expect(code).to.be.equal('Unidentified');
61 expect(down).to.be.equal(false);
62 done();
63 }
747b4623 64 };
9e99ce12
PO
65 kbd._handleKeyDown(keyevent('keydown', {code: 'Unidentified', key: 'a'}));
66 });
9e99ce12
PO
67 });
68
2c5491e1 69 describe('Track Key State', function () {
2c5491e1 70 it('should send release using the same keysym as the press', function (done) {
2b5f94fa 71 const kbd = new Keyboard(document);
651c23ec 72 kbd.onkeyevent = (keysym, code, down) => {
f7363fd2
PO
73 expect(keysym).to.be.equal(0x61);
74 expect(code).to.be.equal('KeyA');
75 if (!down) {
76 done();
77 }
747b4623 78 };
f7363fd2
PO
79 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
80 kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'b'}));
f00b6fb6 81 });
2c5491e1 82 it('should send the same keysym for multiple presses', function () {
2b5f94fa
JD
83 let count = 0;
84 const kbd = new Keyboard(document);
651c23ec 85 kbd.onkeyevent = (keysym, code, down) => {
ae820533
PO
86 expect(keysym).to.be.equal(0x61);
87 expect(code).to.be.equal('KeyA');
88 expect(down).to.be.equal(true);
89 count++;
747b4623 90 };
ae820533
PO
91 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
92 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'b'}));
93 expect(count).to.be.equal(2);
94 });
2c5491e1 95 it('should do nothing on keyup events if no keys are down', function () {
2b5f94fa 96 const kbd = new Keyboard(document);
747b4623 97 kbd.onkeyevent = sinon.spy();
f7363fd2 98 kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
747b4623 99 expect(kbd.onkeyevent).to.not.have.been.called;
f7363fd2 100 });
7e79dfe4 101
2c5491e1
PO
102 describe('Legacy Events', function () {
103 it('should track keys using keyCode if no code', function (done) {
2b5f94fa 104 const kbd = new Keyboard(document);
651c23ec 105 kbd.onkeyevent = (keysym, code, down) => {
7e79dfe4
PO
106 expect(keysym).to.be.equal(0x61);
107 expect(code).to.be.equal('Platform65');
108 if (!down) {
109 done();
110 }
747b4623 111 };
7e79dfe4
PO
112 kbd._handleKeyDown(keyevent('keydown', {keyCode: 65, key: 'a'}));
113 kbd._handleKeyUp(keyevent('keyup', {keyCode: 65, key: 'b'}));
114 });
2c5491e1 115 it('should ignore compositing code', function () {
2b5f94fa 116 const kbd = new Keyboard(document);
651c23ec 117 kbd.onkeyevent = (keysym, code, down) => {
4093c37f
PO
118 expect(keysym).to.be.equal(0x61);
119 expect(code).to.be.equal('Unidentified');
747b4623 120 };
4093c37f
PO
121 kbd._handleKeyDown(keyevent('keydown', {keyCode: 229, key: 'a'}));
122 });
2c5491e1 123 it('should track keys using keyIdentifier if no code', function (done) {
2b5f94fa 124 const kbd = new Keyboard(document);
651c23ec 125 kbd.onkeyevent = (keysym, code, down) => {
7e79dfe4
PO
126 expect(keysym).to.be.equal(0x61);
127 expect(code).to.be.equal('Platform65');
128 if (!down) {
129 done();
130 }
747b4623 131 };
7e79dfe4
PO
132 kbd._handleKeyDown(keyevent('keydown', {keyIdentifier: 'U+0041', key: 'a'}));
133 kbd._handleKeyUp(keyevent('keyup', {keyIdentifier: 'U+0041', key: 'b'}));
134 });
135 });
f7363fd2 136 });
f00b6fb6 137
2c5491e1 138 describe('Shuffle modifiers on macOS', function () {
2b5f94fa 139 let origNavigator;
bf43c263
PO
140 beforeEach(function () {
141 // window.navigator is a protected read-only property in many
142 // environments, so we need to redefine it whilst running these
143 // tests.
144 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
bf43c263
PO
145
146 Object.defineProperty(window, "navigator", {value: {}});
147 if (window.navigator.platform !== undefined) {
148 // Object.defineProperty() doesn't work properly in old
149 // versions of Chrome
150 this.skip();
151 }
152
153 window.navigator.platform = "Mac x86_64";
154 });
155 afterEach(function () {
eb05b45b
PO
156 if (origNavigator !== undefined) {
157 Object.defineProperty(window, "navigator", origNavigator);
158 }
bf43c263
PO
159 });
160
2c5491e1 161 it('should change Alt to AltGraph', function () {
2b5f94fa
JD
162 let count = 0;
163 const kbd = new Keyboard(document);
651c23ec 164 kbd.onkeyevent = (keysym, code, down) => {
bf43c263
PO
165 switch (count++) {
166 case 0:
167 expect(keysym).to.be.equal(0xFF7E);
168 expect(code).to.be.equal('AltLeft');
169 break;
170 case 1:
171 expect(keysym).to.be.equal(0xFE03);
172 expect(code).to.be.equal('AltRight');
173 break;
174 }
747b4623 175 };
9782d4a3
PO
176 kbd._handleKeyDown(keyevent('keydown', {code: 'AltLeft', key: 'Alt', location: 1}));
177 kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
bf43c263
PO
178 expect(count).to.be.equal(2);
179 });
2c5491e1 180 it('should change left Super to Alt', function (done) {
2b5f94fa 181 const kbd = new Keyboard(document);
651c23ec 182 kbd.onkeyevent = (keysym, code, down) => {
bf43c263
PO
183 expect(keysym).to.be.equal(0xFFE9);
184 expect(code).to.be.equal('MetaLeft');
185 done();
747b4623 186 };
9782d4a3 187 kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1}));
bf43c263 188 });
2c5491e1 189 it('should change right Super to left Super', function (done) {
2b5f94fa 190 const kbd = new Keyboard(document);
651c23ec 191 kbd.onkeyevent = (keysym, code, down) => {
bf43c263
PO
192 expect(keysym).to.be.equal(0xFFEB);
193 expect(code).to.be.equal('MetaRight');
194 done();
747b4623 195 };
9782d4a3 196 kbd._handleKeyDown(keyevent('keydown', {code: 'MetaRight', key: 'Meta', location: 2}));
bf43c263
PO
197 });
198 });
199
a6304f91
AT
200 describe('Caps Lock on iOS and macOS', function () {
201 let origNavigator;
202 beforeEach(function () {
203 // window.navigator is a protected read-only property in many
204 // environments, so we need to redefine it whilst running these
205 // tests.
206 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
a6304f91
AT
207
208 Object.defineProperty(window, "navigator", {value: {}});
209 if (window.navigator.platform !== undefined) {
210 // Object.defineProperty() doesn't work properly in old
211 // versions of Chrome
212 this.skip();
213 }
214 });
215
216 afterEach(function () {
eb05b45b
PO
217 if (origNavigator !== undefined) {
218 Object.defineProperty(window, "navigator", origNavigator);
219 }
a6304f91
AT
220 });
221
4ae9d3e7 222 it('should toggle caps lock on key press on iOS', function () {
a6304f91
AT
223 window.navigator.platform = "iPad";
224 const kbd = new Keyboard(document);
225 kbd.onkeyevent = sinon.spy();
226 kbd._handleKeyDown(keyevent('keydown', {code: 'CapsLock', key: 'CapsLock'}));
227
228 expect(kbd.onkeyevent).to.have.been.calledTwice;
229 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
230 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
a6304f91
AT
231 });
232
4ae9d3e7 233 it('should toggle caps lock on key press on mac', function () {
a6304f91
AT
234 window.navigator.platform = "Mac";
235 const kbd = new Keyboard(document);
236 kbd.onkeyevent = sinon.spy();
237 kbd._handleKeyDown(keyevent('keydown', {code: 'CapsLock', key: 'CapsLock'}));
238
239 expect(kbd.onkeyevent).to.have.been.calledTwice;
240 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
241 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
a6304f91
AT
242 });
243
4ae9d3e7 244 it('should toggle caps lock on key release on iOS', function () {
a6304f91
AT
245 window.navigator.platform = "iPad";
246 const kbd = new Keyboard(document);
247 kbd.onkeyevent = sinon.spy();
248 kbd._handleKeyUp(keyevent('keyup', {code: 'CapsLock', key: 'CapsLock'}));
249
250 expect(kbd.onkeyevent).to.have.been.calledTwice;
251 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
252 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
a6304f91
AT
253 });
254
4ae9d3e7 255 it('should toggle caps lock on key release on mac', function () {
a6304f91
AT
256 window.navigator.platform = "Mac";
257 const kbd = new Keyboard(document);
258 kbd.onkeyevent = sinon.spy();
259 kbd._handleKeyUp(keyevent('keyup', {code: 'CapsLock', key: 'CapsLock'}));
260
261 expect(kbd.onkeyevent).to.have.been.calledTwice;
262 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
263 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
a6304f91
AT
264 });
265 });
266
0cdf2962
PO
267 describe('Japanese IM keys on Windows', function () {
268 let origNavigator;
269 beforeEach(function () {
270 // window.navigator is a protected read-only property in many
271 // environments, so we need to redefine it whilst running these
272 // tests.
273 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
274
275 Object.defineProperty(window, "navigator", {value: {}});
276 if (window.navigator.platform !== undefined) {
277 // Object.defineProperty() doesn't work properly in old
278 // versions of Chrome
279 this.skip();
280 }
281
282 window.navigator.platform = "Windows";
283 });
284
285 afterEach(function () {
286 if (origNavigator !== undefined) {
287 Object.defineProperty(window, "navigator", origNavigator);
288 }
289 });
290
291 const keys = { 'Zenkaku': 0xff2a, 'Hankaku': 0xff2a,
292 'Alphanumeric': 0xff30, 'Katakana': 0xff26,
293 'Hiragana': 0xff25, 'Romaji': 0xff24,
294 'KanaMode': 0xff24 };
295 for (let [key, keysym] of Object.entries(keys)) {
296 it(`should fake key release for ${key} on Windows`, function () {
297 let kbd = new Keyboard(document);
298 kbd.onkeyevent = sinon.spy();
299 kbd._handleKeyDown(keyevent('keydown', {code: 'FakeIM', key: key}));
300
301 expect(kbd.onkeyevent).to.have.been.calledTwice;
302 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(keysym, "FakeIM", true);
303 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(keysym, "FakeIM", false);
304 });
305 }
306 });
307
2c5491e1 308 describe('Escape AltGraph on Windows', function () {
2b5f94fa 309 let origNavigator;
f7363fd2
PO
310 beforeEach(function () {
311 // window.navigator is a protected read-only property in many
312 // environments, so we need to redefine it whilst running these
313 // tests.
314 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
f7363fd2
PO
315
316 Object.defineProperty(window, "navigator", {value: {}});
317 if (window.navigator.platform !== undefined) {
318 // Object.defineProperty() doesn't work properly in old
319 // versions of Chrome
320 this.skip();
321 }
322
323 window.navigator.platform = "Windows x86_64";
b22c9ef9
PO
324
325 this.clock = sinon.useFakeTimers();
f7363fd2
PO
326 });
327 afterEach(function () {
eb05b45b
PO
328 if (origNavigator !== undefined) {
329 Object.defineProperty(window, "navigator", origNavigator);
330 }
331 if (this.clock !== undefined) {
332 this.clock.restore();
333 }
f7363fd2
PO
334 });
335
b22c9ef9 336 it('should supress ControlLeft until it knows if it is AltGr', function () {
2b5f94fa 337 const kbd = new Keyboard(document);
b22c9ef9 338 kbd.onkeyevent = sinon.spy();
9782d4a3 339 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
b22c9ef9 340 expect(kbd.onkeyevent).to.not.have.been.called;
f7363fd2 341 });
b22c9ef9
PO
342
343 it('should not trigger on repeating ControlLeft', function () {
2b5f94fa 344 const kbd = new Keyboard(document);
b22c9ef9 345 kbd.onkeyevent = sinon.spy();
9782d4a3 346 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
b22c9ef9
PO
347 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
348 expect(kbd.onkeyevent).to.have.been.calledTwice;
349 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
350 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
f7363fd2 351 });
b22c9ef9
PO
352
353 it('should not supress ControlRight', function () {
2b5f94fa 354 const kbd = new Keyboard(document);
b22c9ef9
PO
355 kbd.onkeyevent = sinon.spy();
356 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlRight', key: 'Control', location: 2}));
357 expect(kbd.onkeyevent).to.have.been.calledOnce;
358 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe4, "ControlRight", true);
359 });
360
361 it('should release ControlLeft after 100 ms', function () {
2b5f94fa 362 const kbd = new Keyboard(document);
b22c9ef9 363 kbd.onkeyevent = sinon.spy();
9782d4a3 364 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
b22c9ef9
PO
365 expect(kbd.onkeyevent).to.not.have.been.called;
366 this.clock.tick(100);
367 expect(kbd.onkeyevent).to.have.been.calledOnce;
368 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe3, "ControlLeft", true);
369 });
370
371 it('should release ControlLeft on other key press', function () {
2b5f94fa 372 const kbd = new Keyboard(document);
b22c9ef9
PO
373 kbd.onkeyevent = sinon.spy();
374 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
375 expect(kbd.onkeyevent).to.not.have.been.called;
376 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
377 expect(kbd.onkeyevent).to.have.been.calledTwice;
378 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
379 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0x61, "KeyA", true);
380
381 // Check that the timer is properly dead
c9765e50 382 kbd.onkeyevent.resetHistory();
b22c9ef9
PO
383 this.clock.tick(100);
384 expect(kbd.onkeyevent).to.not.have.been.called;
385 });
386
387 it('should release ControlLeft on other key release', function () {
2b5f94fa 388 const kbd = new Keyboard(document);
b22c9ef9
PO
389 kbd.onkeyevent = sinon.spy();
390 kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
9782d4a3 391 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
b22c9ef9
PO
392 expect(kbd.onkeyevent).to.have.been.calledOnce;
393 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0x61, "KeyA", true);
394 kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
395 expect(kbd.onkeyevent).to.have.been.calledThrice;
396 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
397 expect(kbd.onkeyevent.thirdCall).to.have.been.calledWith(0x61, "KeyA", false);
398
399 // Check that the timer is properly dead
c9765e50 400 kbd.onkeyevent.resetHistory();
b22c9ef9
PO
401 this.clock.tick(100);
402 expect(kbd.onkeyevent).to.not.have.been.called;
403 });
404
405 it('should generate AltGraph for quick Ctrl+Alt sequence', function () {
2b5f94fa 406 const kbd = new Keyboard(document);
b22c9ef9
PO
407 kbd.onkeyevent = sinon.spy();
408 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
409 this.clock.tick(20);
410 kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2, timeStamp: Date.now()}));
411 expect(kbd.onkeyevent).to.have.been.calledOnce;
412 expect(kbd.onkeyevent).to.have.been.calledWith(0xfe03, 'AltRight', true);
413
414 // Check that the timer is properly dead
c9765e50 415 kbd.onkeyevent.resetHistory();
b22c9ef9
PO
416 this.clock.tick(100);
417 expect(kbd.onkeyevent).to.not.have.been.called;
418 });
419
420 it('should generate Ctrl, Alt for slow Ctrl+Alt sequence', function () {
2b5f94fa 421 const kbd = new Keyboard(document);
b22c9ef9
PO
422 kbd.onkeyevent = sinon.spy();
423 kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
424 this.clock.tick(60);
425 kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2, timeStamp: Date.now()}));
426 expect(kbd.onkeyevent).to.have.been.calledTwice;
427 expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
428 expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffea, "AltRight", true);
429
430 // Check that the timer is properly dead
c9765e50 431 kbd.onkeyevent.resetHistory();
b22c9ef9
PO
432 this.clock.tick(100);
433 expect(kbd.onkeyevent).to.not.have.been.called;
434 });
435
436 it('should pass through single Alt', function () {
2b5f94fa 437 const kbd = new Keyboard(document);
b22c9ef9
PO
438 kbd.onkeyevent = sinon.spy();
439 kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
440 expect(kbd.onkeyevent).to.have.been.calledOnce;
441 expect(kbd.onkeyevent).to.have.been.calledWith(0xffea, 'AltRight', true);
442 });
443
444 it('should pass through single AltGr', function () {
2b5f94fa 445 const kbd = new Keyboard(document);
b22c9ef9
PO
446 kbd.onkeyevent = sinon.spy();
447 kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'AltGraph', location: 2}));
448 expect(kbd.onkeyevent).to.have.been.calledOnce;
449 expect(kbd.onkeyevent).to.have.been.calledWith(0xfe03, 'AltRight', true);
f00b6fb6 450 });
451 });
ccb511a5
PO
452
453 describe('Missing Shift keyup on Windows', function () {
454 let origNavigator;
455 beforeEach(function () {
456 // window.navigator is a protected read-only property in many
457 // environments, so we need to redefine it whilst running these
458 // tests.
459 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
ccb511a5
PO
460
461 Object.defineProperty(window, "navigator", {value: {}});
462 if (window.navigator.platform !== undefined) {
463 // Object.defineProperty() doesn't work properly in old
464 // versions of Chrome
465 this.skip();
466 }
467
468 window.navigator.platform = "Windows x86_64";
469
470 this.clock = sinon.useFakeTimers();
471 });
472 afterEach(function () {
eb05b45b
PO
473 if (origNavigator !== undefined) {
474 Object.defineProperty(window, "navigator", origNavigator);
475 }
476 if (this.clock !== undefined) {
477 this.clock.restore();
478 }
ccb511a5
PO
479 });
480
481 it('should fake a left Shift keyup', function () {
482 const kbd = new Keyboard(document);
483 kbd.onkeyevent = sinon.spy();
484
485 kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftLeft', key: 'Shift', location: 1}));
486 expect(kbd.onkeyevent).to.have.been.calledOnce;
487 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', true);
488 kbd.onkeyevent.resetHistory();
489
490 kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftRight', key: 'Shift', location: 2}));
491 expect(kbd.onkeyevent).to.have.been.calledOnce;
492 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', true);
493 kbd.onkeyevent.resetHistory();
494
495 kbd._handleKeyUp(keyevent('keyup', {code: 'ShiftLeft', key: 'Shift', location: 1}));
496 expect(kbd.onkeyevent).to.have.been.calledTwice;
497 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', false);
498 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', false);
499 });
500
501 it('should fake a right Shift keyup', function () {
502 const kbd = new Keyboard(document);
503 kbd.onkeyevent = sinon.spy();
504
505 kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftLeft', key: 'Shift', location: 1}));
506 expect(kbd.onkeyevent).to.have.been.calledOnce;
507 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', true);
508 kbd.onkeyevent.resetHistory();
509
510 kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftRight', key: 'Shift', location: 2}));
511 expect(kbd.onkeyevent).to.have.been.calledOnce;
512 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', true);
513 kbd.onkeyevent.resetHistory();
514
515 kbd._handleKeyUp(keyevent('keyup', {code: 'ShiftRight', key: 'Shift', location: 2}));
516 expect(kbd.onkeyevent).to.have.been.calledTwice;
517 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', false);
518 expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', false);
519 });
520 });
f00b6fb6 521});