]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/test.keyboard.js
1 const expect
= chai
.expect
;
3 import Keyboard
from '../core/input/keyboard.js';
4 import * as browser
from '../core/util/browser.js';
6 describe('Key Event Handling', function () {
9 // The real KeyboardEvent constructor might not work everywhere we
10 // want to run these tests
11 function keyevent(typeArg
, KeyboardEventInit
) {
12 const e
= { type
: typeArg
};
13 for (let key
in KeyboardEventInit
) {
14 e
[key
] = KeyboardEventInit
[key
];
16 e
.stopPropagation
= sinon
.spy();
17 e
.preventDefault
= sinon
.spy();
21 describe('Decode Keyboard Events', function () {
22 it('should decode keydown events', function (done
) {
23 if (browser
.isIE() || browser
.isEdge()) this.skip();
24 const kbd
= new Keyboard(document
);
25 kbd
.onkeyevent
= (keysym
, code
, down
) => {
26 expect(keysym
).to
.be
.equal(0x61);
27 expect(code
).to
.be
.equal('KeyA');
28 expect(down
).to
.be
.equal(true);
31 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
33 it('should decode keyup events', function (done
) {
34 if (browser
.isIE() || browser
.isEdge()) this.skip();
36 const kbd
= new Keyboard(document
);
37 kbd
.onkeyevent
= (keysym
, code
, down
) => {
38 expect(keysym
).to
.be
.equal(0x61);
39 expect(code
).to
.be
.equal('KeyA');
41 expect(down
).to
.be
.equal(false);
45 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
46 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
49 describe('Legacy keypress Events', function () {
50 it('should wait for keypress when needed', function () {
51 const kbd
= new Keyboard(document
);
52 kbd
.onkeyevent
= sinon
.spy();
53 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
54 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
56 it('should decode keypress events', function (done
) {
57 const kbd
= new Keyboard(document
);
58 kbd
.onkeyevent
= (keysym
, code
, down
) => {
59 expect(keysym
).to
.be
.equal(0x61);
60 expect(code
).to
.be
.equal('KeyA');
61 expect(down
).to
.be
.equal(true);
64 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
65 kbd
._handleKeyPress(keyevent('keypress', {code
: 'KeyA', charCode
: 0x61}));
67 it('should ignore keypress with different code', function () {
68 const kbd
= new Keyboard(document
);
69 kbd
.onkeyevent
= sinon
.spy();
70 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
71 kbd
._handleKeyPress(keyevent('keypress', {code
: 'KeyB', charCode
: 0x61}));
72 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
74 it('should handle keypress with missing code', function (done
) {
75 const kbd
= new Keyboard(document
);
76 kbd
.onkeyevent
= (keysym
, code
, down
) => {
77 expect(keysym
).to
.be
.equal(0x61);
78 expect(code
).to
.be
.equal('KeyA');
79 expect(down
).to
.be
.equal(true);
82 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
83 kbd
._handleKeyPress(keyevent('keypress', {charCode
: 0x61}));
85 it('should guess key if no keypress and numeric key', function (done
) {
86 const kbd
= new Keyboard(document
);
87 kbd
.onkeyevent
= (keysym
, code
, down
) => {
88 expect(keysym
).to
.be
.equal(0x32);
89 expect(code
).to
.be
.equal('Digit2');
90 expect(down
).to
.be
.equal(true);
93 kbd
._handleKeyDown(keyevent('keydown', {code
: 'Digit2', keyCode
: 0x32}));
95 it('should guess key if no keypress and alpha key', function (done
) {
96 const kbd
= new Keyboard(document
);
97 kbd
.onkeyevent
= (keysym
, code
, down
) => {
98 expect(keysym
).to
.be
.equal(0x61);
99 expect(code
).to
.be
.equal('KeyA');
100 expect(down
).to
.be
.equal(true);
103 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41, shiftKey
: false}));
105 it('should guess key if no keypress and alpha key (with shift)', function (done
) {
106 const kbd
= new Keyboard(document
);
107 kbd
.onkeyevent
= (keysym
, code
, down
) => {
108 expect(keysym
).to
.be
.equal(0x41);
109 expect(code
).to
.be
.equal('KeyA');
110 expect(down
).to
.be
.equal(true);
113 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41, shiftKey
: true}));
115 it('should not guess key if no keypress and unknown key', function (done
) {
116 const kbd
= new Keyboard(document
);
117 kbd
.onkeyevent
= (keysym
, code
, down
) => {
118 expect(keysym
).to
.be
.equal(0);
119 expect(code
).to
.be
.equal('KeyA');
120 expect(down
).to
.be
.equal(true);
123 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x09}));
127 describe('suppress the right events at the right time', function () {
128 beforeEach(function () {
129 if (browser
.isIE() || browser
.isEdge()) this.skip();
131 it('should suppress anything with a valid key', function () {
132 const kbd
= new Keyboard(document
, {});
133 const evt1
= keyevent('keydown', {code
: 'KeyA', key
: 'a'});
134 kbd
._handleKeyDown(evt1
);
135 expect(evt1
.preventDefault
).to
.have
.been
.called
;
136 const evt2
= keyevent('keyup', {code
: 'KeyA', key
: 'a'});
137 kbd
._handleKeyUp(evt2
);
138 expect(evt2
.preventDefault
).to
.have
.been
.called
;
140 it('should not suppress keys without key', function () {
141 const kbd
= new Keyboard(document
, {});
142 const evt
= keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41});
143 kbd
._handleKeyDown(evt
);
144 expect(evt
.preventDefault
).to
.not
.have
.been
.called
;
146 it('should suppress the following keypress event', function () {
147 const kbd
= new Keyboard(document
, {});
148 const evt1
= keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41});
149 kbd
._handleKeyDown(evt1
);
150 const evt2
= keyevent('keypress', {code
: 'KeyA', charCode
: 0x41});
151 kbd
._handleKeyPress(evt2
);
152 expect(evt2
.preventDefault
).to
.have
.been
.called
;
157 describe('Fake keyup', function () {
158 it('should fake keyup events for virtual keyboards', function (done
) {
159 if (browser
.isIE() || browser
.isEdge()) this.skip();
161 const kbd
= new Keyboard(document
);
162 kbd
.onkeyevent
= (keysym
, code
, down
) => {
165 expect(keysym
).to
.be
.equal(0x61);
166 expect(code
).to
.be
.equal('Unidentified');
167 expect(down
).to
.be
.equal(true);
170 expect(keysym
).to
.be
.equal(0x61);
171 expect(code
).to
.be
.equal('Unidentified');
172 expect(down
).to
.be
.equal(false);
176 kbd
._handleKeyDown(keyevent('keydown', {code
: 'Unidentified', key
: 'a'}));
180 describe('Track Key State', function () {
181 beforeEach(function () {
182 if (browser
.isIE() || browser
.isEdge()) this.skip();
184 it('should send release using the same keysym as the press', function (done
) {
185 const kbd
= new Keyboard(document
);
186 kbd
.onkeyevent
= (keysym
, code
, down
) => {
187 expect(keysym
).to
.be
.equal(0x61);
188 expect(code
).to
.be
.equal('KeyA');
193 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
194 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'b'}));
196 it('should send the same keysym for multiple presses', function () {
198 const kbd
= new Keyboard(document
);
199 kbd
.onkeyevent
= (keysym
, code
, down
) => {
200 expect(keysym
).to
.be
.equal(0x61);
201 expect(code
).to
.be
.equal('KeyA');
202 expect(down
).to
.be
.equal(true);
205 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
206 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'b'}));
207 expect(count
).to
.be
.equal(2);
209 it('should do nothing on keyup events if no keys are down', function () {
210 const kbd
= new Keyboard(document
);
211 kbd
.onkeyevent
= sinon
.spy();
212 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
213 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
216 describe('Legacy Events', function () {
217 it('should track keys using keyCode if no code', function (done
) {
218 const kbd
= new Keyboard(document
);
219 kbd
.onkeyevent
= (keysym
, code
, down
) => {
220 expect(keysym
).to
.be
.equal(0x61);
221 expect(code
).to
.be
.equal('Platform65');
226 kbd
._handleKeyDown(keyevent('keydown', {keyCode
: 65, key
: 'a'}));
227 kbd
._handleKeyUp(keyevent('keyup', {keyCode
: 65, key
: 'b'}));
229 it('should ignore compositing code', function () {
230 const kbd
= new Keyboard(document
);
231 kbd
.onkeyevent
= (keysym
, code
, down
) => {
232 expect(keysym
).to
.be
.equal(0x61);
233 expect(code
).to
.be
.equal('Unidentified');
235 kbd
._handleKeyDown(keyevent('keydown', {keyCode
: 229, key
: 'a'}));
237 it('should track keys using keyIdentifier if no code', function (done
) {
238 const kbd
= new Keyboard(document
);
239 kbd
.onkeyevent
= (keysym
, code
, down
) => {
240 expect(keysym
).to
.be
.equal(0x61);
241 expect(code
).to
.be
.equal('Platform65');
246 kbd
._handleKeyDown(keyevent('keydown', {keyIdentifier
: 'U+0041', key
: 'a'}));
247 kbd
._handleKeyUp(keyevent('keyup', {keyIdentifier
: 'U+0041', key
: 'b'}));
252 describe('Shuffle modifiers on macOS', function () {
254 beforeEach(function () {
255 // window.navigator is a protected read-only property in many
256 // environments, so we need to redefine it whilst running these
258 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
259 if (origNavigator
=== undefined) {
260 // Object.getOwnPropertyDescriptor() doesn't work
261 // properly in any version of IE
265 Object
.defineProperty(window
, "navigator", {value
: {}});
266 if (window
.navigator
.platform
!== undefined) {
267 // Object.defineProperty() doesn't work properly in old
268 // versions of Chrome
272 window
.navigator
.platform
= "Mac x86_64";
274 afterEach(function () {
275 if (origNavigator
!== undefined) {
276 Object
.defineProperty(window
, "navigator", origNavigator
);
280 it('should change Alt to AltGraph', function () {
282 const kbd
= new Keyboard(document
);
283 kbd
.onkeyevent
= (keysym
, code
, down
) => {
286 expect(keysym
).to
.be
.equal(0xFF7E);
287 expect(code
).to
.be
.equal('AltLeft');
290 expect(keysym
).to
.be
.equal(0xFE03);
291 expect(code
).to
.be
.equal('AltRight');
295 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltLeft', key
: 'Alt', location
: 1}));
296 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2}));
297 expect(count
).to
.be
.equal(2);
299 it('should change left Super to Alt', function (done
) {
300 const kbd
= new Keyboard(document
);
301 kbd
.onkeyevent
= (keysym
, code
, down
) => {
302 expect(keysym
).to
.be
.equal(0xFFE9);
303 expect(code
).to
.be
.equal('MetaLeft');
306 kbd
._handleKeyDown(keyevent('keydown', {code
: 'MetaLeft', key
: 'Meta', location
: 1}));
308 it('should change right Super to left Super', function (done
) {
309 const kbd
= new Keyboard(document
);
310 kbd
.onkeyevent
= (keysym
, code
, down
) => {
311 expect(keysym
).to
.be
.equal(0xFFEB);
312 expect(code
).to
.be
.equal('MetaRight');
315 kbd
._handleKeyDown(keyevent('keydown', {code
: 'MetaRight', key
: 'Meta', location
: 2}));
319 describe('Caps Lock on iOS and macOS', function () {
321 beforeEach(function () {
322 // window.navigator is a protected read-only property in many
323 // environments, so we need to redefine it whilst running these
325 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
326 if (origNavigator
=== undefined) {
327 // Object.getOwnPropertyDescriptor() doesn't work
328 // properly in any version of IE
332 Object
.defineProperty(window
, "navigator", {value
: {}});
333 if (window
.navigator
.platform
!== undefined) {
334 // Object.defineProperty() doesn't work properly in old
335 // versions of Chrome
340 afterEach(function () {
341 if (origNavigator
!== undefined) {
342 Object
.defineProperty(window
, "navigator", origNavigator
);
346 it('should toggle caps lock on key press on iOS', function (done
) {
347 window
.navigator
.platform
= "iPad";
348 const kbd
= new Keyboard(document
);
349 kbd
.onkeyevent
= sinon
.spy();
350 kbd
._handleKeyDown(keyevent('keydown', {code
: 'CapsLock', key
: 'CapsLock'}));
352 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
353 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", true);
354 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", false);
358 it('should toggle caps lock on key press on mac', function (done
) {
359 window
.navigator
.platform
= "Mac";
360 const kbd
= new Keyboard(document
);
361 kbd
.onkeyevent
= sinon
.spy();
362 kbd
._handleKeyDown(keyevent('keydown', {code
: 'CapsLock', key
: 'CapsLock'}));
364 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
365 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", true);
366 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", false);
370 it('should toggle caps lock on key release on iOS', function (done
) {
371 window
.navigator
.platform
= "iPad";
372 const kbd
= new Keyboard(document
);
373 kbd
.onkeyevent
= sinon
.spy();
374 kbd
._handleKeyUp(keyevent('keyup', {code
: 'CapsLock', key
: 'CapsLock'}));
376 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
377 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", true);
378 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", false);
382 it('should toggle caps lock on key release on mac', function (done
) {
383 window
.navigator
.platform
= "Mac";
384 const kbd
= new Keyboard(document
);
385 kbd
.onkeyevent
= sinon
.spy();
386 kbd
._handleKeyUp(keyevent('keyup', {code
: 'CapsLock', key
: 'CapsLock'}));
388 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
389 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", true);
390 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xFFE5, "CapsLock", false);
395 describe('Escape AltGraph on Windows', function () {
397 beforeEach(function () {
398 // window.navigator is a protected read-only property in many
399 // environments, so we need to redefine it whilst running these
401 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
402 if (origNavigator
=== undefined) {
403 // Object.getOwnPropertyDescriptor() doesn't work
404 // properly in any version of IE
408 Object
.defineProperty(window
, "navigator", {value
: {}});
409 if (window
.navigator
.platform
!== undefined) {
410 // Object.defineProperty() doesn't work properly in old
411 // versions of Chrome
415 window
.navigator
.platform
= "Windows x86_64";
417 this.clock
= sinon
.useFakeTimers();
419 afterEach(function () {
420 if (origNavigator
!== undefined) {
421 Object
.defineProperty(window
, "navigator", origNavigator
);
423 if (this.clock
!== undefined) {
424 this.clock
.restore();
428 it('should supress ControlLeft until it knows if it is AltGr', function () {
429 const kbd
= new Keyboard(document
);
430 kbd
.onkeyevent
= sinon
.spy();
431 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
432 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
435 it('should not trigger on repeating ControlLeft', function () {
436 const kbd
= new Keyboard(document
);
437 kbd
.onkeyevent
= sinon
.spy();
438 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
439 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
440 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
441 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
442 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
445 it('should not supress ControlRight', function () {
446 const kbd
= new Keyboard(document
);
447 kbd
.onkeyevent
= sinon
.spy();
448 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlRight', key
: 'Control', location
: 2}));
449 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
450 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe4, "ControlRight", true);
453 it('should release ControlLeft after 100 ms', function () {
454 const kbd
= new Keyboard(document
);
455 kbd
.onkeyevent
= sinon
.spy();
456 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
457 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
458 this.clock
.tick(100);
459 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
460 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
463 it('should release ControlLeft on other key press', function () {
464 const kbd
= new Keyboard(document
);
465 kbd
.onkeyevent
= sinon
.spy();
466 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
467 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
468 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
469 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
470 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
471 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0x61, "KeyA", true);
473 // Check that the timer is properly dead
474 kbd
.onkeyevent
.resetHistory();
475 this.clock
.tick(100);
476 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
479 it('should release ControlLeft on other key release', function () {
480 const kbd
= new Keyboard(document
);
481 kbd
.onkeyevent
= sinon
.spy();
482 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
483 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
484 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
485 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0x61, "KeyA", true);
486 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
487 expect(kbd
.onkeyevent
).to
.have
.been
.calledThrice
;
488 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
489 expect(kbd
.onkeyevent
.thirdCall
).to
.have
.been
.calledWith(0x61, "KeyA", false);
491 // Check that the timer is properly dead
492 kbd
.onkeyevent
.resetHistory();
493 this.clock
.tick(100);
494 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
497 it('should generate AltGraph for quick Ctrl+Alt sequence', function () {
498 const kbd
= new Keyboard(document
);
499 kbd
.onkeyevent
= sinon
.spy();
500 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1, timeStamp
: Date
.now()}));
502 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2, timeStamp
: Date
.now()}));
503 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
504 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xfe03, 'AltRight', true);
506 // Check that the timer is properly dead
507 kbd
.onkeyevent
.resetHistory();
508 this.clock
.tick(100);
509 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
512 it('should generate Ctrl, Alt for slow Ctrl+Alt sequence', function () {
513 const kbd
= new Keyboard(document
);
514 kbd
.onkeyevent
= sinon
.spy();
515 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1, timeStamp
: Date
.now()}));
517 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2, timeStamp
: Date
.now()}));
518 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
519 expect(kbd
.onkeyevent
.firstCall
).to
.have
.been
.calledWith(0xffe3, "ControlLeft", true);
520 expect(kbd
.onkeyevent
.secondCall
).to
.have
.been
.calledWith(0xffea, "AltRight", true);
522 // Check that the timer is properly dead
523 kbd
.onkeyevent
.resetHistory();
524 this.clock
.tick(100);
525 expect(kbd
.onkeyevent
).to
.not
.have
.been
.called
;
528 it('should pass through single Alt', function () {
529 const kbd
= new Keyboard(document
);
530 kbd
.onkeyevent
= sinon
.spy();
531 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2}));
532 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
533 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffea, 'AltRight', true);
536 it('should pass through single AltGr', function () {
537 const kbd
= new Keyboard(document
);
538 kbd
.onkeyevent
= sinon
.spy();
539 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'AltGraph', location
: 2}));
540 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
541 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xfe03, 'AltRight', true);
545 describe('Missing Shift keyup on Windows', function () {
547 beforeEach(function () {
548 // window.navigator is a protected read-only property in many
549 // environments, so we need to redefine it whilst running these
551 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
552 if (origNavigator
=== undefined) {
553 // Object.getOwnPropertyDescriptor() doesn't work
554 // properly in any version of IE
558 Object
.defineProperty(window
, "navigator", {value
: {}});
559 if (window
.navigator
.platform
!== undefined) {
560 // Object.defineProperty() doesn't work properly in old
561 // versions of Chrome
565 window
.navigator
.platform
= "Windows x86_64";
567 this.clock
= sinon
.useFakeTimers();
569 afterEach(function () {
570 if (origNavigator
!== undefined) {
571 Object
.defineProperty(window
, "navigator", origNavigator
);
573 if (this.clock
!== undefined) {
574 this.clock
.restore();
578 it('should fake a left Shift keyup', function () {
579 const kbd
= new Keyboard(document
);
580 kbd
.onkeyevent
= sinon
.spy();
582 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ShiftLeft', key
: 'Shift', location
: 1}));
583 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
584 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe1, 'ShiftLeft', true);
585 kbd
.onkeyevent
.resetHistory();
587 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ShiftRight', key
: 'Shift', location
: 2}));
588 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
589 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe2, 'ShiftRight', true);
590 kbd
.onkeyevent
.resetHistory();
592 kbd
._handleKeyUp(keyevent('keyup', {code
: 'ShiftLeft', key
: 'Shift', location
: 1}));
593 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
594 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe2, 'ShiftRight', false);
595 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe1, 'ShiftLeft', false);
598 it('should fake a right Shift keyup', function () {
599 const kbd
= new Keyboard(document
);
600 kbd
.onkeyevent
= sinon
.spy();
602 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ShiftLeft', key
: 'Shift', location
: 1}));
603 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
604 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe1, 'ShiftLeft', true);
605 kbd
.onkeyevent
.resetHistory();
607 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ShiftRight', key
: 'Shift', location
: 2}));
608 expect(kbd
.onkeyevent
).to
.have
.been
.calledOnce
;
609 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe2, 'ShiftRight', true);
610 kbd
.onkeyevent
.resetHistory();
612 kbd
._handleKeyUp(keyevent('keyup', {code
: 'ShiftRight', key
: 'Shift', location
: 2}));
613 expect(kbd
.onkeyevent
).to
.have
.been
.calledTwice
;
614 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe2, 'ShiftRight', false);
615 expect(kbd
.onkeyevent
).to
.have
.been
.calledWith(0xffe1, 'ShiftLeft', false);