Skip to content

Commit

Permalink
chore(web): converts 'integrated' (e2e-ish) Web auto-tests to TS
Browse files Browse the repository at this point in the history
  • Loading branch information
jahorton committed May 10, 2024
1 parent b6c0aef commit 0bd13ee
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 117 deletions.
2 changes: 1 addition & 1 deletion web/src/app/browser/src/contextManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export default class ContextManager extends ContextManagerBase<BrowserConfigurat
}
}

public setActiveTarget(target: OutputTarget<any>, sendEvents: boolean) {
public setActiveTarget(target: OutputTarget<any>, sendEvents?: boolean) {
const previousTarget = this.mostRecentTarget;
const originalTarget = this.activeTarget; // may differ, depending on focus state.

Expand Down
2 changes: 1 addition & 1 deletion web/src/app/browser/src/keymanEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ export default class KeymanEngine extends KeymanEngineBase<BrowserConfiguration,
* @param {Object|string} e element id or element
* @param {boolean=} setFocus optionally set focus (KMEW-123)
**/
setActiveElement(e: string|HTMLElement, setFocus: boolean) {
setActiveElement(e: string|HTMLElement, setFocus?: boolean) {
if(typeof e == 'string') {
const id = e;
e = document.getElementById(e);
Expand Down
3 changes: 2 additions & 1 deletion web/src/app/browser/src/test-index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { BrowserConfiguration } from './configuration.js';
export { BrowserConfiguration, BrowserInitOptionSpec } from './configuration.js';
export { default as ContextManager, KeyboardCookie } from "./contextManager.js";
export { preprocessKeyboardEvent, default as HardwareEventKeyboard } from './hardwareEventKeyboard.js';

export { default as KeymanEngine } from './keymanEngine.js';
export { default as KeyboardInterface } from './keyboardInterface.js';
export { UIModule } from './uiModuleInterface.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert } from 'chai';

import { DEVICE_DETECT_FAILURE, setupKMW, teardownKMW } from "../test_utils.js";
import { Device } from "keyman/engine/device-detect";
import { KeymanEngine } from "keyman/app/browser";

const baseTimeout = 5000;

Expand Down Expand Up @@ -33,10 +34,13 @@ describe('Basic KeymanWeb', function() {

describe('Initialization', function() {
it('KMW should attach to the input element.', function() {
const keyman = window['keyman'] as KeymanEngine;
var singleton = document.getElementById('singleton');
assert.isTrue(keyman.isAttached(singleton), "KeymanWeb did not automatically attach to the element!");
});

it('KMW\'s initialization variable should indicate completion.', function() {
const keyman = window['keyman'] as KeymanEngine;
assert(keyman.initialized == 2, 'Keyman indicates incomplete initialization!');
});
});
Expand Down Expand Up @@ -65,15 +69,19 @@ if(!device.touchable) {
});

it('The Toggle UI initializes correctly.', function() {
assert(keyman.ui.initialized, 'Initialization flag is set to false!');
const keyman = window['keyman'] as KeymanEngine;

// UI-module specific typings are currently not available.
const ui = keyman.ui as any;

assert.isNotNull(keyman.ui.controller, 'Failed to create the controller element!');
assert(ui.initialized, 'Initialization flag is set to false!');
assert.isNotNull(ui.controller, 'Failed to create the controller element!');

var divs = document.getElementsByTagName("div");
var match = false;

for(var i=0; i < divs.length; i++) {
if(divs[i] == keyman.ui.controller) {
if(divs[i] == ui.controller) {
match = true;
}
}
Expand Down Expand Up @@ -101,7 +109,12 @@ if(!device.touchable) {
});

it('The Button UI initializes correctly.', function() {
assert(keyman.ui.init, 'Initialization flag is set to false!');
const keyman = window['keyman'] as KeymanEngine;

// UI-module specific typings are currently not available.
const ui = keyman.ui as any;

assert(ui.init, 'Initialization flag is set to false!');
})
});

Expand All @@ -124,15 +137,20 @@ if(!device.touchable) {
});

it('The Float UI initializes correctly.', function() {
assert(keyman.ui.initialized, 'Initialization flag is set to false!');
const keyman = window['keyman'] as KeymanEngine;

assert.isNotNull(keyman.ui.outerDiv, 'Failed to create the floating controller element!');
// UI-module specific typings are currently not available.
const ui = keyman.ui as any;

assert(ui.initialized, 'Initialization flag is set to false!');

assert.isNotNull(ui.outerDiv, 'Failed to create the floating controller element!');

var divs = document.getElementsByTagName("div");
var match = false;

for(var i=0; i < divs.length; i++) {
if(divs[i] == keyman.ui.outerDiv) {
if(divs[i] == ui.outerDiv) {
match = true;
}
}
Expand Down Expand Up @@ -160,7 +178,12 @@ if(!device.touchable) {
});

it('The Toolbar UI initializes correctly.', function() {
assert(keyman.ui.init, 'Initialization flag is set to false!');
const keyman = window['keyman'] as KeymanEngine;

// UI-module specific typings are currently not available.
const ui = keyman.ui as any;

assert(ui.init, 'Initialization flag is set to false!');

var kwc = document.getElementById('KeymanWebControl');
assert.isNotNull(kwc, 'Toolbar DIV was not added to the page!');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
} from "../test_utils.js";
import * as KMWRecorder from '#recorder';

import { type KeymanEngine, type KeyboardInterface } from 'keyman/app/browser';
import { type KeyboardStub } from 'keyman/engine/package-cache';
import { type OSKInputEventSpec } from '#recorder';

/** @type {HTMLInputElement} */
let inputElem;

Expand Down Expand Up @@ -46,19 +50,21 @@ describe('Engine - Browser Interactions', function() {
describe('RegisterStub', function() {
it('RegisterStub on same keyboard twice', async function() {
this.timeout(baseTimeout);
const keyman: KeymanEngine = window['keyman'];
const KeymanWeb: KeyboardInterface = window['KeymanWeb'];

await loadKeyboardFromJSON("resources/json/keyboards/lao_2008_basic.json", baseTimeout);

assert.isNotNull(keyman.getKeyboard("lao_2008_basic", "lo"), "Keyboard stub was not registered!");
assert.equal(keyman.getActiveKeyboard(), "Keyboard_lao_2008_basic", "Keyboard not set automatically!");

var stub = {
let stub = {
'KI': 'Keyboard_lao_2008_basic',
'KN': 'Lao 2008 Basic',
'KLC': 'lo',
'KL': 'Lao',
'KF': 'resources/keyboards/lao_2008_basic.js'
};
} as KeyboardStub;

await Promise.resolve();

Expand All @@ -74,22 +80,26 @@ describe('Engine - Browser Interactions', function() {
});

after(function() {
const keyman: KeymanEngine = window['keyman'];
keyman.removeKeyboards('options_with_save');
});

it('Backing up and restoring (loadStore/saveStore)', function() {
const keyman: KeymanEngine = window['keyman'];
const KeymanWeb: KeyboardInterface = window['KeymanWeb'];

// Keyboard's default value is 0, corresponding to "no foo."
var keyboardID = "options_with_save";
var prefixedKeyboardID = "Keyboard_" + keyboardID;
var storeName = "foo";

return keyman.setActiveKeyboard(keyboardID, 'en').then(function() {
// Alas, saveStore itself requires the keyboard to be active!
KeymanWeb.saveStore(storeName, 1);
KeymanWeb.saveStore(storeName, '1');

// First, ensure that we get the same thing if we load the value immediately.
var value = KeymanWeb.loadStore(prefixedKeyboardID, storeName, 0);
assert.equal(value, 1, "loadStore did not see the value saved to initialize the test before resetting keyboard");
var value = KeymanWeb.loadStore(prefixedKeyboardID, storeName, '0');
assert.equal(value, '1', "loadStore did not see the value saved to initialize the test before resetting keyboard");

// Reload the keyboard so that we can test its loaded value.
keyman.removeKeyboards(keyboardID);
Expand All @@ -101,20 +111,23 @@ describe('Engine - Browser Interactions', function() {
return keyman.setActiveKeyboard(keyboardID, 'en');
}).then(() => {
// This requires proper storage to a cookie, as we'll be on a new instance of the same keyboard.
var value = KeymanWeb.loadStore(prefixedKeyboardID, storeName, 0);
assert.equal(value, 1, "Did not properly save and reload variable store setting");
var value = KeymanWeb.loadStore(prefixedKeyboardID, storeName, '0');
assert.equal(value, '1', "Did not properly save and reload variable store setting");
}).finally(() => {
KeymanWeb.saveStore(storeName, 0);
KeymanWeb.saveStore(storeName, '0');
});
});

it("Multiple-sequence check", function() {
this.timeout(baseTimeout + baseTimeout * 3);
const keyman: KeymanEngine = window['keyman'];
const KeymanWeb: KeyboardInterface = window['KeymanWeb'];

var keyboardID = "options_with_save";
var storeName = "foo";

return keyman.setActiveKeyboard(keyboardID, 'en').then(async function() {
KeymanWeb.saveStore(storeName, 1);
KeymanWeb.saveStore(storeName, '1');
keyman.removeKeyboards(keyboardID);

await Promise.resolve();
Expand Down Expand Up @@ -145,16 +158,18 @@ describe('Engine - Browser Interactions', function() {
this.timeout(baseTimeout);

before(function() {
this.timeout = baseTimeout;
this.timeout(baseTimeout);
return loadKeyboardFromJSON("resources/json/keyboards/lao_2008_basic.json", baseTimeout);
});

beforeEach(function() {
const keyman: KeymanEngine = window['keyman'];
keyman.setActiveElement(inputElem);
inputElem.value = "";
});

after(function() {
const keyman: KeymanEngine = window['keyman'];
keyman.removeKeyboards('lao_2008_basic');
});

Expand All @@ -179,7 +194,7 @@ describe('Engine - Browser Interactions', function() {

it('Simple OSK click', async function() {
var lao_s_osk_json = {"type": "osk", "keyID": 'shift-K_S'};
var lao_s_event = new KMWRecorder.OSKInputEventSpec(lao_s_osk_json);
var lao_s_event = new KMWRecorder.OSKInputEventSpec(lao_s_osk_json as OSKInputEventSpec);

let eventDriver = new KMWRecorder.BrowserDriver(inputElem);
await eventDriver.simulateEvent(lao_s_event);
Expand Down Expand Up @@ -258,6 +273,8 @@ describe('Engine - Browser Interactions', function() {
describe('Keyboard Loading', function() {
it('Local', function() {
this.timeout(baseTimeout);
const keyman: KeymanEngine = window['keyman'];
const KeymanWeb: KeyboardInterface = window['KeymanWeb'];

return loadKeyboardFromJSON("resources/json/keyboards/lao_2008_basic.json",
baseTimeout).then(async function() {
Expand All @@ -272,14 +289,16 @@ describe('Engine - Browser Interactions', function() {

it('Automatically sets first available keyboard', function() {
this.timeout(2 * baseTimeout);
const keyman: KeymanEngine = window['keyman'];
const KeymanWeb: KeyboardInterface = window['KeymanWeb'];

return loadKeyboardFromJSON("resources/json/keyboards/lao_2008_basic.json",
baseTimeout,
{passive: true}).then(() => {
// Because we're loading the keyboard 'passively', KMW's setActiveKeyboard function is auto-called
// on the stub-add. That specific call (for first keyboard auto-activation) is outside of KMW's
// current Promise chain, so we can't _directly_ rely on a KMW Promise to test it.
return new Promise((resolve) => {
return new Promise<void>((resolve) => {
let hasResolved = false;
// So, we give KMW the time needed for auto-activation to happen, polling a bit actively so that we don't
// wait unnecessarily long after it occurs.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { assert } from 'chai';

import {
loadKeyboardFromJSON,
runKeyboardTestFromJSON,
setupKMW,
teardownKMW
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import {
teardownKMW
} from "../test_utils.js";
import * as KMWRecorder from '#recorder';
import OSKInputEventSpec = KMWRecorder.OSKInputEventSpec;

import { timedPromise } from '@keymanapp/web-utils';
import { type KeymanEngine } from 'keyman/app/browser';

const host = document.createElement('div');
document.body.appendChild(host);
Expand Down Expand Up @@ -47,6 +50,8 @@ describe('Event Management', function() {
});

it('Keystroke-based onChange event generation', async function() {
const keyman: KeymanEngine = window['keyman'];

var simple_A = {"type":"key","key":"a","code":"KeyA","keyCode":65,"modifierSet":0,"location":0};
var event = new KMWRecorder.PhysicalInputEventSpec(simple_A);

Expand All @@ -70,8 +75,9 @@ describe('Event Management', function() {
});

it('OSK-based onChange event generation', async function() {
const keyman: KeymanEngine = window['keyman'];
var simple_A = {"type":"osk","keyID":"default-K_A"};
var event = new KMWRecorder.OSKInputEventSpec(simple_A);
var event = new KMWRecorder.OSKInputEventSpec(simple_A as OSKInputEventSpec);

var ele = document.getElementById('input');

Expand All @@ -98,6 +104,7 @@ describe('Event Management', function() {
});

it('Keystroke-based onInput event generation', async function() {
const keyman: KeymanEngine = window['keyman'];
var simple_A = {"type":"key","key":"a","code":"KeyA","keyCode":65,"modifierSet":0,"location":0};
var event = new KMWRecorder.PhysicalInputEventSpec(simple_A);

Expand All @@ -120,8 +127,9 @@ describe('Event Management', function() {
});

it('OSK-based onInput event generation', async function() {
const keyman: KeymanEngine = window['keyman'];
var simple_A = {"type":"osk","keyID":"default-K_A"};
var event = new KMWRecorder.OSKInputEventSpec(simple_A);
var event = new KMWRecorder.OSKInputEventSpec(simple_A as OSKInputEventSpec);

var ele = document.getElementById('input');
keyman.setActiveElement(ele);
Expand Down
Loading

0 comments on commit 0bd13ee

Please sign in to comment.