// test-runner const KEYBOARDS_RELATIVE_PATH = "/keyboards/"; const TEST_BATCH_SIZE = 100; // or Infinity var receiver; var windowLoad = new Promise(function(resolve, reject) { window.addEventListener('load', function() { // Initialise KeymanWeb keyman.init({ attachType: 'auto', resources: '/web/' }); // Configure receiver - for UI mode we have one already receiver = document.getElementById('receiver'); if(!receiver) { // When running tests, we dynamically create the receiver receiver = document.createElement('input'); document.body.appendChild(receiver); let d0 = document.createElement('div'); d0.id = 'progressWindow'; d0.style.width = '100%'; d0.style.margin = '8px 0'; d0.style.height = '16px'; d0.style.border = 'solid 1px #666666'; d0.style.boxSizing = 'border-box'; d0.style.padding = '2px'; let d1 = document.createElement('div'); d1.id = 'progressPosition'; d1.style.background = '#44cc44'; d1.style.height = '100%'; d1.style.boxSizing = 'border-box'; d0.appendChild(d1); document.body.insertBefore(d0, receiver); } keyman.attachToControl(receiver); keyman.setKeyboardForControl(receiver, '', ''); resolve(); }); }); function chunk(arr, chunkSize) { var R = []; for (var i=0,len=arr.length; i Object.assign({id: key}, data.inputTests[key])); this.keyboards[data.keyboard.id] = data; }, /** * Removes a keyboard and associated tests from memory * @param {string} locator shortname/id, e.g. k/kayan */ unregister: function(locator) { let {shortname, id} = this.parseLocator(locator); if(!id) throw new Error('Invalid locator '+locator); keyman.removeKeyboards(id); delete this.keyboards[id]; }, /** * Run all tests for all loaded keyboards */ runAllTests: function() { for(var k in this.keyboards) { this.runTests(k); } }, /** * Run all tests for a given keyboard * @param {string} id Keyboard identifier */ runTests: function(keyboardId) { return new Promise(function(resolve, reject) { this.keyboards[keyboardId].results = {}; console.log('-- Running '+this.keyboards[keyboardId].inputTests.length+' tests for '+keyboardId+'.'); var chunkSize = TEST_BATCH_SIZE; // Batch tests into group s of chunkSize. This means we don't // run into issues of the browser stalling on very long runs. var tests = chunk(this.keyboards[keyboardId].inputTests, chunkSize), n = 0; this.initProgress(tests.length); var f = function() { var testChunk = tests.shift(); testChunk.forEach((v) => this.runTest(keyboardId, v.id)); this.updateProgress(this.max - tests.length); if(tests.length) { window.setTimeout(f.bind(this), 1); } else { resolve(this.keyboards[keyboardId].results); } }; if(tests.length) window.setTimeout(f.bind(this), 1); }.bind(this)); }, /** * Run a single test for a keyboard * @param {string} id Keyboard identifier * @param {string|number} index Test identifier */ runTest: function(keyboardId, testId) { let test = this.keyboards[keyboardId].inputTests.find((v) => v.id == testId); if(test !== undefined) { //console.log('Running test '+id+':'+index); try { keyman.interface.resetContext(); receiver.value = test.context || ''; // Keyman 12 now uses com.keyman.text.KeyEvent let e = com.keyman.KeyEvent ? new com.keyman.KeyEvent() : new com.keyman.text.KeyEvent(); e.Ltarg = receiver; e.Lcode = test.key; e.Lstates = 0; // caps, etc TODO e.LmodifierChange = true; e.Lmodifiers = test.modifier ? test.modifier : 0; e.LisVirtualKeyCode = true; e.LisVirtualKey = true; e.vkCode = test.key; // Keyman 12 changes the processKeystroke interface keyman.interface.processKeystroke(keyman.util.physicalDevice, com.keyman.text ? com.keyman.text.Processor.getOutputTarget(receiver) : receiver, e); this.keyboards[keyboardId].results[testId] = receiver.value; } catch(err) { console.warn(err.toString()); this.keyboards[keyboardId].results[testId] = {error: err.message, filename: err.filename, lineno: err.lineno}; if(!knownFailures[keyboardId]) { return false; } } return true; } }, /** * Initialises the progress bar when running tests in UI mode * @param {number} max Maximum length of progress bar */ initProgress: function(max) { this.max = max; this.progressPosition = document.getElementById('progressPosition'); if(this.progressPosition) this.progressPosition.style.width = '0px'; }, /** * Updates the progress bar when running tests in UI mode * @param {number} len Current position of progress bar */ updateProgress: function(len) { if(this.progressPosition) this.progressPosition.style.width = Math.round(len / this.max * 100).toString() + '%'; } };