aboutsummaryrefslogtreecommitdiff
path: root/test/content/InputDriver.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test/content/InputDriver.test.ts')
-rw-r--r--test/content/InputDriver.test.ts129
1 files changed, 129 insertions, 0 deletions
diff --git a/test/content/InputDriver.test.ts b/test/content/InputDriver.test.ts
new file mode 100644
index 0000000..ac5f95d
--- /dev/null
+++ b/test/content/InputDriver.test.ts
@@ -0,0 +1,129 @@
+import InputDriver from '../../src/content/InputDriver';
+import { expect } from 'chai';
+import { Key } from '../../src/shared/utils/keys';
+
+describe('InputDriver', () => {
+ let target: HTMLElement;
+ let driver: InputDriver;
+
+ beforeEach(() => {
+ target = document.createElement('div');
+ document.body.appendChild(target);
+ driver = new InputDriver(target);
+ });
+
+ afterEach(() => {
+ target.remove();
+ target = null;
+ driver = null;
+ });
+
+ it('register callbacks', (done) => {
+ driver.onKey((key: Key): boolean => {
+ expect(key.key).to.equal('a');
+ expect(key.ctrlKey).to.be.true;
+ expect(key.shiftKey).to.be.false;
+ expect(key.altKey).to.be.false;
+ expect(key.metaKey).to.be.false;
+ done();
+ return true;
+ });
+
+ target.dispatchEvent(new KeyboardEvent('keydown', {
+ key: 'a',
+ ctrlKey: true,
+ shiftKey: false,
+ altKey: false,
+ metaKey: false,
+ }));
+ });
+
+ it('invoke callback once', () => {
+ let a = 0, b = 0;
+ driver.onKey((key: Key): boolean => {
+ if (key.key == 'a') {
+ ++a;
+ } else {
+ key.key == 'b'
+ ++b;
+ }
+ return true;
+ });
+
+ let events = [
+ new KeyboardEvent('keydown', { key: 'a' }),
+ new KeyboardEvent('keydown', { key: 'b' }),
+ new KeyboardEvent('keypress', { key: 'a' }),
+ new KeyboardEvent('keyup', { key: 'a' }),
+ new KeyboardEvent('keypress', { key: 'b' }),
+ new KeyboardEvent('keyup', { key: 'b' }),
+ ];
+ for (let e of events) {
+ target.dispatchEvent(e);
+ }
+
+ expect(a).to.equal(1);
+ expect(b).to.equal(1);
+ })
+
+ it('propagates and stop handler chain', () => {
+ let a = 0, b = 0, c = 0;
+ driver.onKey((key: Key): boolean => {
+ a++;
+ return false;
+ });
+ driver.onKey((key: Key): boolean => {
+ b++;
+ return true;
+ });
+ driver.onKey((key: Key): boolean => {
+ c++;
+ return true;
+ });
+
+ target.dispatchEvent(new KeyboardEvent('keydown', { key: 'b' }));
+
+ expect(a).to.equal(1);
+ expect(b).to.equal(1);
+ expect(c).to.equal(0);
+ })
+
+ it('does not invoke only meta keys', () => {
+ driver.onKey((key: Key): boolean=> {
+ expect.fail();
+ return false;
+ });
+
+ target.dispatchEvent(new KeyboardEvent('keydown', { key: 'Shift' }));
+ target.dispatchEvent(new KeyboardEvent('keydown', { key: 'Control' }));
+ target.dispatchEvent(new KeyboardEvent('keydown', { key: 'Alt' }));
+ target.dispatchEvent(new KeyboardEvent('keydown', { key: 'OS' }));
+ })
+
+ it('ignores events from input elements', () => {
+ ['input', 'textarea', 'select'].forEach((name) => {
+ let input = window.document.createElement(name);
+ let driver = new InputDriver(input);
+ driver.onKey((key: Key): boolean => {
+ expect.fail();
+ return false;
+ });
+ input.dispatchEvent(new KeyboardEvent('keydown', { key: 'x' }));
+ });
+ });
+
+ it('ignores events from contenteditable elements', () => {
+ let div = window.document.createElement('div');
+ let driver = new InputDriver(div);
+ driver.onKey((key: Key): boolean => {
+ expect.fail();
+ return false;
+ });
+
+ div.setAttribute('contenteditable', '');
+ div.dispatchEvent(new KeyboardEvent('keydown', { key: 'x' }));
+
+ div.setAttribute('contenteditable', 'true');
+ div.dispatchEvent(new KeyboardEvent('keydown', { key: 'x' }));
+ });
+});