spellchecker-spec.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { BrowserWindow, Session, session } from 'electron/main';
  2. import { expect } from 'chai';
  3. import * as path from 'path';
  4. import { closeWindow } from './window-helpers';
  5. import { emittedOnce } from './events-helpers';
  6. import { ifit, ifdescribe, delay } from './spec-helpers';
  7. const features = process._linkedBinding('electron_common_features');
  8. ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', () => {
  9. let w: BrowserWindow;
  10. beforeEach(async () => {
  11. w = new BrowserWindow({
  12. show: false,
  13. webPreferences: {
  14. partition: `unique-spell-${Date.now()}`
  15. }
  16. });
  17. w.webContents.session.setSpellCheckerLanguages(['en-US']);
  18. await w.loadFile(path.resolve(__dirname, './fixtures/chromium/spellchecker.html'));
  19. });
  20. afterEach(async () => {
  21. await closeWindow(w);
  22. });
  23. // Context menu test can not run on Windows, and it is not reliable on ARM
  24. // CI machines.
  25. const shouldRun = process.platform !== 'win32' &&
  26. process.arch !== 'arm' &&
  27. process.arch !== 'arm64';
  28. ifit(shouldRun)('should detect correctly spelled words as correct', async () => {
  29. await w.webContents.executeJavaScript('document.body.querySelector("textarea").value = "Beautiful and lovely"');
  30. await w.webContents.executeJavaScript('document.body.querySelector("textarea").focus()');
  31. const contextMenuPromise = emittedOnce(w.webContents, 'context-menu');
  32. // Wait for spellchecker to load
  33. await delay(500);
  34. w.webContents.sendInputEvent({
  35. type: 'mouseDown',
  36. button: 'right',
  37. x: 43,
  38. y: 42
  39. });
  40. const contextMenuParams: Electron.ContextMenuParams = (await contextMenuPromise)[1];
  41. expect(contextMenuParams.misspelledWord).to.eq('');
  42. expect(contextMenuParams.dictionarySuggestions).to.have.lengthOf(0);
  43. });
  44. ifit(shouldRun)('should detect incorrectly spelled words as incorrect', async () => {
  45. await w.webContents.executeJavaScript('document.body.querySelector("textarea").value = "Beautifulllll asd asd"');
  46. await w.webContents.executeJavaScript('document.body.querySelector("textarea").focus()');
  47. const contextMenuPromise = emittedOnce(w.webContents, 'context-menu');
  48. // Wait for spellchecker to load
  49. await delay(500);
  50. w.webContents.sendInputEvent({
  51. type: 'mouseDown',
  52. button: 'right',
  53. x: 43,
  54. y: 42
  55. });
  56. const contextMenuParams: Electron.ContextMenuParams = (await contextMenuPromise)[1];
  57. expect(contextMenuParams.misspelledWord).to.eq('Beautifulllll');
  58. expect(contextMenuParams.dictionarySuggestions).to.have.length.of.at.least(1);
  59. });
  60. ifit(shouldRun)('should detect incorrectly spelled words as incorrect after disabling all languages and re-enabling', async () => {
  61. w.webContents.session.setSpellCheckerLanguages([]);
  62. await delay(500);
  63. w.webContents.session.setSpellCheckerLanguages(['en-US']);
  64. await w.webContents.executeJavaScript('document.body.querySelector("textarea").value = "Beautifulllll asd asd"');
  65. await w.webContents.executeJavaScript('document.body.querySelector("textarea").focus()');
  66. const contextMenuPromise = emittedOnce(w.webContents, 'context-menu');
  67. // Wait for spellchecker to load
  68. await delay(500);
  69. w.webContents.sendInputEvent({
  70. type: 'mouseDown',
  71. button: 'right',
  72. x: 43,
  73. y: 42
  74. });
  75. const contextMenuParams: Electron.ContextMenuParams = (await contextMenuPromise)[1];
  76. expect(contextMenuParams.misspelledWord).to.eq('Beautifulllll');
  77. expect(contextMenuParams.dictionarySuggestions).to.have.length.of.at.least(1);
  78. });
  79. describe('custom dictionary word list API', () => {
  80. let ses: Session;
  81. beforeEach(async () => {
  82. // ensure a new session runs on each test run
  83. ses = session.fromPartition(`persist:customdictionary-test-${Date.now()}`);
  84. });
  85. afterEach(async () => {
  86. if (ses) {
  87. await ses.clearStorageData();
  88. ses = null as any;
  89. }
  90. });
  91. describe('ses.listWordsFromSpellCheckerDictionary', () => {
  92. it('should successfully list words in custom dictionary', async () => {
  93. const words = ['foo', 'bar', 'baz'];
  94. const results = words.map(word => ses.addWordToSpellCheckerDictionary(word));
  95. expect(results).to.eql([true, true, true]);
  96. const wordList = await ses.listWordsInSpellCheckerDictionary();
  97. expect(wordList).to.have.deep.members(words);
  98. });
  99. it('should return an empty array if no words are added', async () => {
  100. const wordList = await ses.listWordsInSpellCheckerDictionary();
  101. expect(wordList).to.have.length(0);
  102. });
  103. });
  104. describe('ses.addWordToSpellCheckerDictionary', () => {
  105. it('should successfully add word to custom dictionary', async () => {
  106. const result = ses.addWordToSpellCheckerDictionary('foobar');
  107. expect(result).to.equal(true);
  108. const wordList = await ses.listWordsInSpellCheckerDictionary();
  109. expect(wordList).to.eql(['foobar']);
  110. });
  111. it('should fail for an empty string', async () => {
  112. const result = ses.addWordToSpellCheckerDictionary('');
  113. expect(result).to.equal(false);
  114. const wordList = await ses.listWordsInSpellCheckerDictionary;
  115. expect(wordList).to.have.length(0);
  116. });
  117. // remove API will always return false because we can't add words
  118. it('should fail for non-persistent sessions', async () => {
  119. const tempSes = session.fromPartition('temporary');
  120. const result = tempSes.addWordToSpellCheckerDictionary('foobar');
  121. expect(result).to.equal(false);
  122. });
  123. });
  124. describe('ses.removeWordFromSpellCheckerDictionary', () => {
  125. it('should successfully remove words to custom dictionary', async () => {
  126. const result1 = ses.addWordToSpellCheckerDictionary('foobar');
  127. expect(result1).to.equal(true);
  128. const wordList1 = await ses.listWordsInSpellCheckerDictionary();
  129. expect(wordList1).to.eql(['foobar']);
  130. const result2 = ses.removeWordFromSpellCheckerDictionary('foobar');
  131. expect(result2).to.equal(true);
  132. const wordList2 = await ses.listWordsInSpellCheckerDictionary();
  133. expect(wordList2).to.have.length(0);
  134. });
  135. it('should fail for words not in custom dictionary', () => {
  136. const result2 = ses.removeWordFromSpellCheckerDictionary('foobar');
  137. expect(result2).to.equal(false);
  138. });
  139. });
  140. });
  141. });