// Enter sends, or makes a newline, and the person decides. Two rules hold // whatever they choose: Shift+Enter is always a newline, Ctrl/Cmd+Enter always // sends. Those are the habits people arrive with. const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const src = fs.readFileSync(path.join(__dirname, '..', 'public/js/clinicalAssistant.js'), 'utf8'); const handler = src.slice(src.indexOf("input.addEventListener('keydown'"), src.indexOf('var enterToggle')); test('Ctrl or Cmd + Enter always sends, whatever the preference', () => { assert.match(handler, /if \(\(e\.ctrlKey \|\| e\.metaKey\)\) \{ e\.preventDefault\(\); onAsk\(e\); return; \}/); // It is checked before the preference, so it cannot be switched off. assert.ok(handler.indexOf('ctrlKey') < handler.indexOf('enterSends()'), 'the modifier must win over the preference'); }); test('Shift+Enter is always a newline, whatever the preference', () => { assert.match(handler, /if \(e\.shiftKey \|\| e\.altKey\) return;/); assert.ok(handler.indexOf('shiftKey') < handler.indexOf('enterSends()')); }); test('an IME composition keystroke never sends', () => { // Enter accepts a candidate word in Chinese, Japanese, Korean and on // predictive Android keyboards. Sending there cuts a sentence mid-word. assert.match(handler, /if \(e\.isComposing \|\| e\.keyCode === 229\) return;/); assert.ok(handler.indexOf('isComposing') < handler.indexOf('ctrlKey'), 'composition is checked before anything can send'); }); test('the preference is per device, and survives storage being unavailable', () => { const pref = src.slice(src.indexOf('function enterSends()'), src.indexOf('function applyEnterHint')); assert.match(pref, /localStorage\.getItem\(ENTER_KEY\)/); assert.match(pref, /catch \(e\)/, 'a private window must not throw here'); // Unset defaults by device class rather than guessing one answer for both. assert.match(pref, /\(hover: none\) and \(pointer: coarse\)/); }); test('the toggle reflects and writes the preference', () => { const bind = src.slice(src.indexOf('var enterToggle'), src.indexOf('bindExampleButtons')); assert.match(bind, /enterToggle\.checked = enterSends\(\)/, 'opens showing the current state'); assert.match(bind, /setEnterSends\(enterToggle\.checked\)/); const html = fs.readFileSync(path.join(__dirname, '..', 'public/components/assistant.html'), 'utf8'); assert.match(html, /id="assistant-enter-sends"/); }); test('the composer says which key sends', () => { assert.match(src, /Enter sends · Shift\+Enter for a new line/); assert.match(src, /Enter for a new line · Ctrl\+Enter sends/); });