]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/test.keyboard.js
1 var assert
= chai
.assert
;
2 var expect
= chai
.expect
;
4 import { Keyboard
} from '../core/input/devices.js';
5 import keysyms
from '../core/input/keysymdef.js';
6 import * as KeyboardUtil
from '../core/input/util.js';
9 return navigator
&& !!(/trident/i).exec(navigator
.userAgent
);
12 return navigator
&& !!(/edge/i).exec(navigator
.userAgent
);
15 /* jshint newcap: false, expr: true */
16 describe('Key Event Handling', function() {
19 // The real KeyboardEvent constructor might not work everywhere we
20 // want to run these tests
21 function keyevent(typeArg
, KeyboardEventInit
) {
22 var e
= { type
: typeArg
};
23 for (var key
in KeyboardEventInit
) {
24 e
[key
] = KeyboardEventInit
[key
];
26 e
.stopPropagation
= sinon
.spy();
27 e
.preventDefault
= sinon
.spy();
31 describe('Decode Keyboard Events', function() {
32 it('should decode keydown events', function(done
) {
33 if (isIE() || isEdge()) this.skip();
34 var kbd
= new Keyboard({
35 onKeyEvent: function(keysym
, code
, down
) {
36 expect(keysym
).to
.be
.equal(0x61);
37 expect(code
).to
.be
.equal('KeyA');
38 expect(down
).to
.be
.equal(true);
41 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
43 it('should decode keyup events', function(done
) {
44 if (isIE() || isEdge()) this.skip();
46 var kbd
= new Keyboard({
47 onKeyEvent: function(keysym
, code
, down
) {
48 expect(keysym
).to
.be
.equal(0x61);
49 expect(code
).to
.be
.equal('KeyA');
51 expect(down
).to
.be
.equal(false);
55 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
56 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
59 describe('Legacy keypress Events', function() {
60 it('should wait for keypress when needed', function() {
61 var callback
= sinon
.spy();
62 var kbd
= new Keyboard({onKeyEvent
: callback
});
63 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
64 expect(callback
).to
.not
.have
.been
.called
;
66 it('should decode keypress events', function(done
) {
67 var kbd
= new Keyboard({
68 onKeyEvent: function(keysym
, code
, down
) {
69 expect(keysym
).to
.be
.equal(0x61);
70 expect(code
).to
.be
.equal('KeyA');
71 expect(down
).to
.be
.equal(true);
74 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
75 kbd
._handleKeyPress(keyevent('keypress', {code
: 'KeyA', charCode
: 0x61}));
77 it('should ignore keypress with different code', function() {
78 var callback
= sinon
.spy();
79 var kbd
= new Keyboard({onKeyEvent
: callback
});
80 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
81 kbd
._handleKeyPress(keyevent('keypress', {code
: 'KeyB', charCode
: 0x61}));
82 expect(callback
).to
.not
.have
.been
.called
;
84 it('should handle keypress with missing code', function(done
) {
85 var kbd
= new Keyboard({
86 onKeyEvent: function(keysym
, code
, down
) {
87 expect(keysym
).to
.be
.equal(0x61);
88 expect(code
).to
.be
.equal('KeyA');
89 expect(down
).to
.be
.equal(true);
92 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41}));
93 kbd
._handleKeyPress(keyevent('keypress', {charCode
: 0x61}));
97 describe('suppress the right events at the right time', function() {
98 beforeEach(function () {
99 if (isIE() || isEdge()) this.skip();
101 it('should suppress anything with a valid key', function() {
102 var kbd
= new Keyboard({});
103 var evt
= keyevent('keydown', {code
: 'KeyA', key
: 'a'});
104 kbd
._handleKeyDown(evt
);
105 expect(evt
.preventDefault
).to
.have
.been
.called
;
106 evt
= keyevent('keyup', {code
: 'KeyA', key
: 'a'});
107 kbd
._handleKeyUp(evt
);
108 expect(evt
.preventDefault
).to
.have
.been
.called
;
110 it('should not suppress keys without key', function() {
111 var kbd
= new Keyboard({});
112 var evt
= keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41});
113 kbd
._handleKeyDown(evt
);
114 expect(evt
.preventDefault
).to
.not
.have
.been
.called
;
116 it('should suppress the following keypress event', function() {
117 var kbd
= new Keyboard({});
118 var evt
= keyevent('keydown', {code
: 'KeyA', keyCode
: 0x41});
119 kbd
._handleKeyDown(evt
);
120 var evt
= keyevent('keypress', {code
: 'KeyA', charCode
: 0x41});
121 kbd
._handleKeyPress(evt
);
122 expect(evt
.preventDefault
).to
.have
.been
.called
;
127 describe('Track Key State', function() {
128 beforeEach(function () {
129 if (isIE() || isEdge()) this.skip();
131 it('should send release using the same keysym as the press', function(done
) {
132 var kbd
= new Keyboard({
133 onKeyEvent: function(keysym
, code
, down
) {
134 expect(keysym
).to
.be
.equal(0x61);
135 expect(code
).to
.be
.equal('KeyA');
140 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
141 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'b'}));
143 it('should send the same keysym for multiple presses', function() {
145 var kbd
= new Keyboard({
146 onKeyEvent: function(keysym
, code
, down
) {
147 expect(keysym
).to
.be
.equal(0x61);
148 expect(code
).to
.be
.equal('KeyA');
149 expect(down
).to
.be
.equal(true);
152 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
153 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'b'}));
154 expect(count
).to
.be
.equal(2);
156 it('should do nothing on keyup events if no keys are down', function() {
157 var callback
= sinon
.spy();
158 var kbd
= new Keyboard({onKeyEvent
: callback
});
159 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
160 expect(callback
).to
.not
.have
.been
.called
;
163 describe('Legacy Events', function() {
164 it('should track keys using keyCode if no code', function(done
) {
165 var kbd
= new Keyboard({
166 onKeyEvent: function(keysym
, code
, down
) {
167 expect(keysym
).to
.be
.equal(0x61);
168 expect(code
).to
.be
.equal('Platform65');
173 kbd
._handleKeyDown(keyevent('keydown', {keyCode
: 65, key
: 'a'}));
174 kbd
._handleKeyUp(keyevent('keyup', {keyCode
: 65, key
: 'b'}));
176 it('should track keys using keyIdentifier if no code', function(done
) {
177 var kbd
= new Keyboard({
178 onKeyEvent: function(keysym
, code
, down
) {
179 expect(keysym
).to
.be
.equal(0x61);
180 expect(code
).to
.be
.equal('Platform65');
185 kbd
._handleKeyDown(keyevent('keydown', {keyIdentifier
: 'U+0041', key
: 'a'}));
186 kbd
._handleKeyUp(keyevent('keyup', {keyIdentifier
: 'U+0041', key
: 'b'}));
191 describe('Shuffle modifiers on macOS', function() {
193 beforeEach(function () {
194 // window.navigator is a protected read-only property in many
195 // environments, so we need to redefine it whilst running these
197 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
198 if (origNavigator
=== undefined) {
199 // Object.getOwnPropertyDescriptor() doesn't work
200 // properly in any version of IE
204 Object
.defineProperty(window
, "navigator", {value
: {}});
205 if (window
.navigator
.platform
!== undefined) {
206 // Object.defineProperty() doesn't work properly in old
207 // versions of Chrome
211 window
.navigator
.platform
= "Mac x86_64";
213 afterEach(function () {
214 Object
.defineProperty(window
, "navigator", origNavigator
);
217 it('should change Alt to AltGraph', function() {
219 var kbd
= new Keyboard({
220 onKeyEvent: function(keysym
, code
, down
) {
223 expect(keysym
).to
.be
.equal(0xFF7E);
224 expect(code
).to
.be
.equal('AltLeft');
227 expect(keysym
).to
.be
.equal(0xFE03);
228 expect(code
).to
.be
.equal('AltRight');
232 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltLeft', key
: 'Alt', location
: 1}));
233 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2}));
234 expect(count
).to
.be
.equal(2);
236 it('should change left Super to Alt', function(done
) {
237 var kbd
= new Keyboard({
238 onKeyEvent: function(keysym
, code
, down
) {
239 expect(keysym
).to
.be
.equal(0xFFE9);
240 expect(code
).to
.be
.equal('MetaLeft');
243 kbd
._handleKeyDown(keyevent('keydown', {code
: 'MetaLeft', key
: 'Meta', location
: 1}));
245 it('should change right Super to left Super', function(done
) {
246 var kbd
= new Keyboard({
247 onKeyEvent: function(keysym
, code
, down
) {
248 expect(keysym
).to
.be
.equal(0xFFEB);
249 expect(code
).to
.be
.equal('MetaRight');
252 kbd
._handleKeyDown(keyevent('keydown', {code
: 'MetaRight', key
: 'Meta', location
: 2}));
256 describe('Escape AltGraph on Windows', function() {
258 beforeEach(function () {
259 // window.navigator is a protected read-only property in many
260 // environments, so we need to redefine it whilst running these
262 origNavigator
= Object
.getOwnPropertyDescriptor(window
, "navigator");
263 if (origNavigator
=== undefined) {
264 // Object.getOwnPropertyDescriptor() doesn't work
265 // properly in any version of IE
269 Object
.defineProperty(window
, "navigator", {value
: {}});
270 if (window
.navigator
.platform
!== undefined) {
271 // Object.defineProperty() doesn't work properly in old
272 // versions of Chrome
276 window
.navigator
.platform
= "Windows x86_64";
278 afterEach(function () {
279 Object
.defineProperty(window
, "navigator", origNavigator
);
282 it('should generate fake undo/redo events on press when AltGraph is down', function() {
283 var times_called
= 0;
284 var kbd
= new Keyboard({
285 onKeyEvent: function(keysym
, code
, down
) {
286 switch(times_called
++) {
288 expect(keysym
).to
.be
.equal(0xFFE3);
289 expect(code
).to
.be
.equal('ControlLeft');
290 expect(down
).to
.be
.equal(true);
293 expect(keysym
).to
.be
.equal(0xFFEA);
294 expect(code
).to
.be
.equal('AltRight');
295 expect(down
).to
.be
.equal(true);
298 expect(keysym
).to
.be
.equal(0xFFEA);
299 expect(code
).to
.be
.equal('AltRight');
300 expect(down
).to
.be
.equal(false);
303 expect(keysym
).to
.be
.equal(0xFFE3);
304 expect(code
).to
.be
.equal('ControlLeft');
305 expect(down
).to
.be
.equal(false);
308 expect(keysym
).to
.be
.equal(0x61);
309 expect(code
).to
.be
.equal('KeyA');
310 expect(down
).to
.be
.equal(true);
313 expect(keysym
).to
.be
.equal(0xFFE3);
314 expect(code
).to
.be
.equal('ControlLeft');
315 expect(down
).to
.be
.equal(true);
318 expect(keysym
).to
.be
.equal(0xFFEA);
319 expect(code
).to
.be
.equal('AltRight');
320 expect(down
).to
.be
.equal(true);
324 // First the modifier combo
325 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
326 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2}));
327 // Next a normal character
328 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
329 expect(times_called
).to
.be
.equal(7);
331 it('should no do anything on key release', function() {
332 var times_called
= 0;
333 var kbd
= new Keyboard({
334 onKeyEvent: function(keysym
, code
, down
) {
335 switch(times_called
++) {
337 expect(keysym
).to
.be
.equal(0x61);
338 expect(code
).to
.be
.equal('KeyA');
339 expect(down
).to
.be
.equal(false);
343 // First the modifier combo
344 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
345 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltRight', key
: 'Alt', location
: 2}));
346 // Next a normal character
347 kbd
._handleKeyDown(keyevent('keydown', {code
: 'KeyA', key
: 'a'}));
348 kbd
._handleKeyUp(keyevent('keyup', {code
: 'KeyA', key
: 'a'}));
349 expect(times_called
).to
.be
.equal(8);
351 it('should not consider a char modifier to be down on the modifier key itself', function() {
352 var times_called
= 0;
353 var kbd
= new Keyboard({
354 onKeyEvent: function(keysym
, code
, down
) {
355 switch(times_called
++) {
357 expect(keysym
).to
.be
.equal(0xFFE3);
358 expect(code
).to
.be
.equal('ControlLeft');
359 expect(down
).to
.be
.equal(true);
362 expect(keysym
).to
.be
.equal(0xFFE9);
363 expect(code
).to
.be
.equal('AltLeft');
364 expect(down
).to
.be
.equal(true);
367 expect(keysym
).to
.be
.equal(0xFFE3);
368 expect(code
).to
.be
.equal('ControlLeft');
369 expect(down
).to
.be
.equal(true);
373 // First the modifier combo
374 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
375 kbd
._handleKeyDown(keyevent('keydown', {code
: 'AltLeft', key
: 'Alt', location
: 1}));
376 // Then one of the keys again
377 kbd
._handleKeyDown(keyevent('keydown', {code
: 'ControlLeft', key
: 'Control', location
: 1}));
378 expect(times_called
).to
.be
.equal(3);