]> git.proxmox.com Git - mirror_novnc.git/blame - tests/test.helper.js
Use standard DOM identifiers for physical keys
[mirror_novnc.git] / tests / test.helper.js
CommitLineData
dfae3209 1var assert = chai.assert;
f00b6fb6 2var expect = chai.expect;
3
dfae3209
SR
4import keysyms from '../core/input/keysymdef.js';
5import * as KeyboardUtil from "../core/input/util.js";
6
f00b6fb6 7describe('Helpers', function() {
8 "use strict";
f00b6fb6 9
524d67f2 10 describe('keysyms.lookup', function() {
f00b6fb6 11 it('should map ASCII characters to keysyms', function() {
524d67f2
PO
12 expect(keysyms.lookup('a'.charCodeAt())).to.be.equal(0x61);
13 expect(keysyms.lookup('A'.charCodeAt())).to.be.equal(0x41);
f00b6fb6 14 });
15 it('should map Latin-1 characters to keysyms', function() {
524d67f2 16 expect(keysyms.lookup('ø'.charCodeAt())).to.be.equal(0xf8);
f00b6fb6 17
524d67f2 18 expect(keysyms.lookup('é'.charCodeAt())).to.be.equal(0xe9);
f00b6fb6 19 });
20 it('should map characters that are in Windows-1252 but not in Latin-1 to keysyms', function() {
524d67f2 21 expect(keysyms.lookup('Š'.charCodeAt())).to.be.equal(0x01a9);
f00b6fb6 22 });
23 it('should map characters which aren\'t in Latin1 *or* Windows-1252 to keysyms', function() {
278a5e7f 24 expect(keysyms.lookup('ũ'.charCodeAt())).to.be.equal(0x03fd);
f00b6fb6 25 });
115eedf6 26 it('should map unknown codepoints to the Unicode range', function() {
524d67f2
PO
27 expect(keysyms.lookup('\n'.charCodeAt())).to.be.equal(0x100000a);
28 expect(keysyms.lookup('\u262D'.charCodeAt())).to.be.equal(0x100262d);
e9ddbec5 29 });
331ae153
SM
30 // This requires very recent versions of most browsers... skipping for now
31 it.skip('should map UCS-4 codepoints to the Unicode range', function() {
524d67f2 32 //expect(keysyms.lookup('\u{1F686}'.codePointAt())).to.be.equal(0x101f686);
f00b6fb6 33 });
34 });
35
80cb8ffd
PO
36 describe('getKeycode', function() {
37 it('should pass through proper code', function() {
38 expect(KeyboardUtil.getKeycode({code: 'Semicolon'})).to.be.equal('Semicolon');
39 });
40 it('should map legacy values', function() {
41 expect(KeyboardUtil.getKeycode({code: ''})).to.be.equal('Unidentified');
42 expect(KeyboardUtil.getKeycode({code: 'OSLeft'})).to.be.equal('MetaLeft');
43 });
44 it('should map keyCode to code when possible', function() {
45 expect(KeyboardUtil.getKeycode({keyCode: 0x14})).to.be.equal('CapsLock');
46 expect(KeyboardUtil.getKeycode({keyCode: 0x5b})).to.be.equal('MetaLeft');
47 expect(KeyboardUtil.getKeycode({keyCode: 0x35})).to.be.equal('Digit5');
48 expect(KeyboardUtil.getKeycode({keyCode: 0x65})).to.be.equal('Numpad5');
49 });
50 it('should map keyCode left/right side', function() {
51 expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 1})).to.be.equal('ShiftLeft');
52 expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 2})).to.be.equal('ShiftRight');
53 expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 1})).to.be.equal('ControlLeft');
54 expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 2})).to.be.equal('ControlRight');
55 });
56 it('should map keyCode on numpad', function() {
57 expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 0})).to.be.equal('Enter');
58 expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 3})).to.be.equal('NumpadEnter');
59 expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 0})).to.be.equal('End');
60 expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 3})).to.be.equal('Numpad1');
61 });
62 it('should return Unidentified when it cannot map the keyCode', function() {
63 expect(KeyboardUtil.getKeycode({keycode: 0x42})).to.be.equal('Unidentified');
64 });
65
66 describe('Fix Meta on macOS', function() {
67 var origNavigator;
68 beforeEach(function () {
69 // window.navigator is a protected read-only property in many
70 // environments, so we need to redefine it whilst running these
71 // tests.
72 origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
73 if (origNavigator === undefined) {
74 // Object.getOwnPropertyDescriptor() doesn't work
75 // properly in any version of IE
76 this.skip();
77 }
78
79 Object.defineProperty(window, "navigator", {value: {}});
80 if (window.navigator.platform !== undefined) {
81 // Object.defineProperty() doesn't work properly in old
82 // versions of Chrome
83 this.skip();
84 }
85
86 window.navigator.platform = "Mac x86_64";
87 });
88 afterEach(function () {
89 Object.defineProperty(window, "navigator", origNavigator);
90 });
91
92 it('should respect ContextMenu on modern browser', function() {
93 expect(KeyboardUtil.getKeycode({code: 'ContextMenu', keyCode: 0x5d})).to.be.equal('ContextMenu');
94 });
95 it('should translate legacy ContextMenu to MetaRight', function() {
96 expect(KeyboardUtil.getKeycode({keyCode: 0x5d})).to.be.equal('MetaRight');
97 });
98 });
99 });
100
f00b6fb6 101 describe('getKeysym', function() {
102 it('should prefer char', function() {
524d67f2 103 expect(KeyboardUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x61);
f00b6fb6 104 });
105 it('should use charCode if no char', function() {
524d67f2
PO
106 expect(KeyboardUtil.getKeysym({char : '', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x01a9);
107 expect(KeyboardUtil.getKeysym({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x01a9);
108 expect(KeyboardUtil.getKeysym({char : 'hello', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x01a9);
f00b6fb6 109 });
110 it('should use keyCode if no charCode', function() {
524d67f2
PO
111 expect(KeyboardUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: false})).to.be.equal(0x62);
112 expect(KeyboardUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: true})).to.be.equal(0x42);
f00b6fb6 113 });
a5c8a755
PO
114 it('should return null for unknown keycodes', function() {
115 expect(KeyboardUtil.getKeysym({keyCode: 0xc0, which: 0xc1, shiftKey:false})).to.be.null;
116 expect(KeyboardUtil.getKeysym({keyCode: 0xde, which: 0xdf, shiftKey:false})).to.be.null;
117 });
f00b6fb6 118 it('should use which if no keyCode', function() {
524d67f2
PO
119 expect(KeyboardUtil.getKeysym({which: 0x43, shiftKey: false})).to.be.equal(0x63);
120 expect(KeyboardUtil.getKeysym({which: 0x43, shiftKey: true})).to.be.equal(0x43);
f00b6fb6 121 });
a5c8a755
PO
122
123 describe('Non-character keys', function() {
124 it('should recognize the right keys', function() {
125 expect(KeyboardUtil.getKeysym({keyCode: 0x0d})).to.be.equal(0xFF0D);
126 expect(KeyboardUtil.getKeysym({keyCode: 0x08})).to.be.equal(0xFF08);
127 expect(KeyboardUtil.getKeysym({keyCode: 0x09})).to.be.equal(0xFF09);
128 expect(KeyboardUtil.getKeysym({keyCode: 0x10})).to.be.equal(0xFFE1);
129 expect(KeyboardUtil.getKeysym({keyCode: 0x11})).to.be.equal(0xFFE3);
130 expect(KeyboardUtil.getKeysym({keyCode: 0x12})).to.be.equal(0xFFE9);
131 expect(KeyboardUtil.getKeysym({keyCode: 0xe0})).to.be.equal(0xFFE7);
132 expect(KeyboardUtil.getKeysym({keyCode: 0xe1})).to.be.equal(0xFE03);
133 expect(KeyboardUtil.getKeysym({keyCode: 0x1b})).to.be.equal(0xFF1B);
134 expect(KeyboardUtil.getKeysym({keyCode: 0x26})).to.be.equal(0xFF52);
135 });
136 it('should not recognize character keys', function() {
137 expect(KeyboardUtil.getKeysym({keyCode: 'A'})).to.be.null;
138 expect(KeyboardUtil.getKeysym({keyCode: '1'})).to.be.null;
139 expect(KeyboardUtil.getKeysym({keyCode: '.'})).to.be.null;
140 expect(KeyboardUtil.getKeysym({keyCode: ' '})).to.be.null;
141 });
142 });
f00b6fb6 143 });
144
145 describe('Modifier Sync', function() { // return a list of fake events necessary to fix modifier state
146 describe('Toggle all modifiers', function() {
ae510306 147 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 148 it ('should do nothing if all modifiers are up as expected', function() {
149 expect(sync.keydown({
150 keyCode: 0x41,
151 ctrlKey: false,
152 altKey: false,
153 altGraphKey: false,
154 shiftKey: false,
155 metaKey: false})
156 ).to.have.lengthOf(0);
157 });
158 it ('should synthesize events if all keys are unexpectedly down', function() {
159 var result = sync.keydown({
160 keyCode: 0x41,
161 ctrlKey: true,
162 altKey: true,
163 altGraphKey: true,
164 shiftKey: true,
165 metaKey: true
166 });
167 expect(result).to.have.lengthOf(5);
168 var keysyms = {};
169 for (var i = 0; i < result.length; ++i) {
170 keysyms[result[i].keysym] = (result[i].type == 'keydown');
171 }
172 expect(keysyms[0xffe3]);
173 expect(keysyms[0xffe9]);
174 expect(keysyms[0xfe03]);
175 expect(keysyms[0xffe1]);
176 expect(keysyms[0xffe7]);
177 });
178 it ('should do nothing if all modifiers are down as expected', function() {
179 expect(sync.keydown({
180 keyCode: 0x41,
181 ctrlKey: true,
182 altKey: true,
183 altGraphKey: true,
184 shiftKey: true,
185 metaKey: true
186 })).to.have.lengthOf(0);
187 });
188 });
189 describe('Toggle Ctrl', function() {
ae510306 190 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 191 it('should sync if modifier is suddenly down', function() {
192 expect(sync.keydown({
193 keyCode: 0x41,
194 ctrlKey: true,
524d67f2 195 })).to.be.deep.equal([{keysym: 0xffe3, type: 'keydown'}]);
f00b6fb6 196 });
197 it('should sync if modifier is suddenly up', function() {
198 expect(sync.keydown({
199 keyCode: 0x41,
200 ctrlKey: false
524d67f2 201 })).to.be.deep.equal([{keysym: 0xffe3, type: 'keyup'}]);
f00b6fb6 202 });
203 });
204 describe('Toggle Alt', function() {
ae510306 205 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 206 it('should sync if modifier is suddenly down', function() {
207 expect(sync.keydown({
208 keyCode: 0x41,
209 altKey: true,
524d67f2 210 })).to.be.deep.equal([{keysym: 0xffe9, type: 'keydown'}]);
f00b6fb6 211 });
212 it('should sync if modifier is suddenly up', function() {
213 expect(sync.keydown({
214 keyCode: 0x41,
215 altKey: false
524d67f2 216 })).to.be.deep.equal([{keysym: 0xffe9, type: 'keyup'}]);
f00b6fb6 217 });
218 });
219 describe('Toggle AltGr', function() {
ae510306 220 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 221 it('should sync if modifier is suddenly down', function() {
222 expect(sync.keydown({
223 keyCode: 0x41,
224 altGraphKey: true,
524d67f2 225 })).to.be.deep.equal([{keysym: 0xfe03, type: 'keydown'}]);
f00b6fb6 226 });
227 it('should sync if modifier is suddenly up', function() {
228 expect(sync.keydown({
229 keyCode: 0x41,
230 altGraphKey: false
524d67f2 231 })).to.be.deep.equal([{keysym: 0xfe03, type: 'keyup'}]);
f00b6fb6 232 });
233 });
234 describe('Toggle Shift', function() {
ae510306 235 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 236 it('should sync if modifier is suddenly down', function() {
237 expect(sync.keydown({
238 keyCode: 0x41,
239 shiftKey: true,
524d67f2 240 })).to.be.deep.equal([{keysym: 0xffe1, type: 'keydown'}]);
f00b6fb6 241 });
242 it('should sync if modifier is suddenly up', function() {
243 expect(sync.keydown({
244 keyCode: 0x41,
245 shiftKey: false
524d67f2 246 })).to.be.deep.equal([{keysym: 0xffe1, type: 'keyup'}]);
f00b6fb6 247 });
248 });
249 describe('Toggle Meta', function() {
ae510306 250 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 251 it('should sync if modifier is suddenly down', function() {
252 expect(sync.keydown({
253 keyCode: 0x41,
254 metaKey: true,
524d67f2 255 })).to.be.deep.equal([{keysym: 0xffe7, type: 'keydown'}]);
f00b6fb6 256 });
257 it('should sync if modifier is suddenly up', function() {
258 expect(sync.keydown({
259 keyCode: 0x41,
260 metaKey: false
524d67f2 261 })).to.be.deep.equal([{keysym: 0xffe7, type: 'keyup'}]);
f00b6fb6 262 });
263 });
264 describe('Modifier keyevents', function() {
265 it('should not sync a modifier on its own events', function() {
ae510306 266 expect(KeyboardUtil.ModifierSync().keydown({
f00b6fb6 267 keyCode: 0x11,
268 ctrlKey: false
269 })).to.be.deep.equal([]);
ae510306 270 expect(KeyboardUtil.ModifierSync().keydown({
f00b6fb6 271 keyCode: 0x11,
272 ctrlKey: true
273 }), 'B').to.be.deep.equal([]);
274 })
275 it('should update state on modifier keyevents', function() {
ae510306 276 var sync = KeyboardUtil.ModifierSync();
f00b6fb6 277 sync.keydown({
278 keyCode: 0x11,
279 });
280 expect(sync.keydown({
281 keyCode: 0x41,
282 ctrlKey: true,
283 })).to.be.deep.equal([]);
284 });
285 it('should sync other modifiers on ctrl events', function() {
ae510306 286 expect(KeyboardUtil.ModifierSync().keydown({
f00b6fb6 287 keyCode: 0x11,
288 altKey: true
524d67f2 289 })).to.be.deep.equal([{keysym: 0xffe9, type: 'keydown'}]);
f00b6fb6 290 })
291 });
292 describe('sync modifiers on non-key events', function() {
293 it('should generate sync events when receiving non-keyboard events', function() {
ae510306 294 expect(KeyboardUtil.ModifierSync().syncAny({
f00b6fb6 295 altKey: true
524d67f2 296 })).to.be.deep.equal([{keysym: 0xffe9, type: 'keydown'}]);
f00b6fb6 297 });
298 });
f6a1d98a
JD
299 describe('do not treat shift as a modifier key', function() {
300 it('should not treat shift as a shortcut modifier', function() {
ae510306 301 expect(KeyboardUtil.hasShortcutModifier([], {0xffe1 : true})).to.be.false;
f6a1d98a
JD
302 });
303 it('should not treat shift as a char modifier', function() {
ae510306 304 expect(KeyboardUtil.hasCharModifier([], {0xffe1 : true})).to.be.false;
f6a1d98a
JD
305 });
306 });
f00b6fb6 307 });
308});