api-web-contents-spec.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. 'use strict'
  2. const assert = require('assert')
  3. const path = require('path')
  4. const {closeWindow} = require('./window-helpers')
  5. const {ipcRenderer, remote} = require('electron')
  6. const {BrowserWindow, webContents, ipcMain} = remote
  7. const isCi = remote.getGlobal('isCi')
  8. describe('webContents module', function () {
  9. const fixtures = path.resolve(__dirname, 'fixtures')
  10. let w
  11. beforeEach(function () {
  12. w = new BrowserWindow({
  13. show: false,
  14. width: 400,
  15. height: 400,
  16. webPreferences: {
  17. backgroundThrottling: false
  18. }
  19. })
  20. })
  21. afterEach(function () {
  22. return closeWindow(w).then(function () { w = null })
  23. })
  24. describe('getAllWebContents() API', function () {
  25. it('returns an array of web contents', function (done) {
  26. w.webContents.on('devtools-opened', function () {
  27. const all = webContents.getAllWebContents().sort(function (a, b) {
  28. return a.getId() - b.getId()
  29. })
  30. assert.ok(all.length >= 4)
  31. assert.equal(all[0].getType(), 'window')
  32. assert.equal(all[all.length - 2].getType(), 'remote')
  33. assert.equal(all[all.length - 1].getType(), 'webview')
  34. done()
  35. })
  36. w.loadURL('file://' + path.join(fixtures, 'pages', 'webview-zoom-factor.html'))
  37. w.webContents.openDevTools()
  38. })
  39. })
  40. describe('getFocusedWebContents() API', function () {
  41. it('returns the focused web contents', function (done) {
  42. if (isCi) return done()
  43. const specWebContents = remote.getCurrentWebContents()
  44. assert.equal(specWebContents.getId(), webContents.getFocusedWebContents().getId())
  45. specWebContents.once('devtools-opened', function () {
  46. assert.equal(specWebContents.devToolsWebContents.getId(), webContents.getFocusedWebContents().getId())
  47. specWebContents.closeDevTools()
  48. })
  49. specWebContents.once('devtools-closed', function () {
  50. assert.equal(specWebContents.getId(), webContents.getFocusedWebContents().getId())
  51. done()
  52. })
  53. specWebContents.openDevTools()
  54. })
  55. it('does not crash when called on a detached dev tools window', function (done) {
  56. const specWebContents = w.webContents
  57. specWebContents.once('devtools-opened', function () {
  58. assert.doesNotThrow(function () {
  59. webContents.getFocusedWebContents()
  60. })
  61. specWebContents.closeDevTools()
  62. })
  63. specWebContents.once('devtools-closed', function () {
  64. assert.doesNotThrow(function () {
  65. webContents.getFocusedWebContents()
  66. })
  67. done()
  68. })
  69. specWebContents.openDevTools({mode: 'detach'})
  70. w.inspectElement(100, 100)
  71. })
  72. })
  73. describe('isFocused() API', function () {
  74. it('returns false when the window is hidden', function () {
  75. BrowserWindow.getAllWindows().forEach(function (window) {
  76. assert.equal(!window.isVisible() && window.webContents.isFocused(), false)
  77. })
  78. })
  79. })
  80. describe('before-input-event event', () => {
  81. it('can prevent document keyboard events', (done) => {
  82. w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'key-events.html'))
  83. w.webContents.once('did-finish-load', () => {
  84. ipcMain.once('keydown', (event, key) => {
  85. assert.equal(key, 'b')
  86. done()
  87. })
  88. ipcRenderer.send('prevent-next-input-event', 'a', w.webContents.id)
  89. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'a'})
  90. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'b'})
  91. })
  92. })
  93. it('has the correct properties', (done) => {
  94. w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'base-page.html'))
  95. w.webContents.once('did-finish-load', () => {
  96. const testBeforeInput = (opts) => {
  97. return new Promise((resolve, reject) => {
  98. w.webContents.once('before-input-event', (event, input) => {
  99. assert.equal(input.type, opts.type)
  100. assert.equal(input.key, opts.key)
  101. assert.equal(input.isAutoRepeat, opts.isAutoRepeat)
  102. assert.equal(input.shift, opts.shift)
  103. assert.equal(input.control, opts.control)
  104. assert.equal(input.alt, opts.alt)
  105. assert.equal(input.meta, opts.meta)
  106. resolve()
  107. })
  108. const modifiers = []
  109. if (opts.shift) modifiers.push('shift')
  110. if (opts.control) modifiers.push('control')
  111. if (opts.alt) modifiers.push('alt')
  112. if (opts.meta) modifiers.push('meta')
  113. if (opts.isAutoRepeat) modifiers.push('isAutoRepeat')
  114. w.webContents.sendInputEvent({
  115. type: opts.type,
  116. keyCode: opts.keyCode,
  117. modifiers: modifiers
  118. })
  119. })
  120. }
  121. Promise.resolve().then(() => {
  122. return testBeforeInput({
  123. type: 'keyDown',
  124. key: 'A',
  125. keyCode: 'a',
  126. shift: true,
  127. control: true,
  128. alt: true,
  129. meta: true,
  130. isAutoRepeat: true
  131. })
  132. }).then(() => {
  133. return testBeforeInput({
  134. type: 'keyUp',
  135. key: '.',
  136. keyCode: '.',
  137. shift: false,
  138. control: true,
  139. alt: true,
  140. meta: false,
  141. isAutoRepeat: false
  142. })
  143. }).then(() => {
  144. return testBeforeInput({
  145. type: 'keyUp',
  146. key: '!',
  147. keyCode: '1',
  148. shift: true,
  149. control: false,
  150. alt: false,
  151. meta: true,
  152. isAutoRepeat: false
  153. })
  154. }).then(() => {
  155. return testBeforeInput({
  156. type: 'keyUp',
  157. key: 'Tab',
  158. keyCode: 'Tab',
  159. shift: false,
  160. control: true,
  161. alt: false,
  162. meta: false,
  163. isAutoRepeat: true
  164. })
  165. }).then(done).catch(done)
  166. })
  167. })
  168. })
  169. describe('sendInputEvent(event)', function () {
  170. beforeEach(function (done) {
  171. w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'key-events.html'))
  172. w.webContents.once('did-finish-load', function () {
  173. done()
  174. })
  175. })
  176. it('can send keydown events', function (done) {
  177. ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
  178. assert.equal(key, 'a')
  179. assert.equal(code, 'KeyA')
  180. assert.equal(keyCode, 65)
  181. assert.equal(shiftKey, false)
  182. assert.equal(ctrlKey, false)
  183. assert.equal(altKey, false)
  184. done()
  185. })
  186. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'})
  187. })
  188. it('can send keydown events with modifiers', function (done) {
  189. ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
  190. assert.equal(key, 'Z')
  191. assert.equal(code, 'KeyZ')
  192. assert.equal(keyCode, 90)
  193. assert.equal(shiftKey, true)
  194. assert.equal(ctrlKey, true)
  195. assert.equal(altKey, false)
  196. done()
  197. })
  198. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl']})
  199. })
  200. it('can send keydown events with special keys', function (done) {
  201. ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
  202. assert.equal(key, 'Tab')
  203. assert.equal(code, 'Tab')
  204. assert.equal(keyCode, 9)
  205. assert.equal(shiftKey, false)
  206. assert.equal(ctrlKey, false)
  207. assert.equal(altKey, true)
  208. done()
  209. })
  210. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Tab', modifiers: ['alt']})
  211. })
  212. it('can send char events', function (done) {
  213. ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
  214. assert.equal(key, 'a')
  215. assert.equal(code, 'KeyA')
  216. assert.equal(keyCode, 65)
  217. assert.equal(shiftKey, false)
  218. assert.equal(ctrlKey, false)
  219. assert.equal(altKey, false)
  220. done()
  221. })
  222. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'})
  223. w.webContents.sendInputEvent({type: 'char', keyCode: 'A'})
  224. })
  225. it('can send char events with modifiers', function (done) {
  226. ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
  227. assert.equal(key, 'Z')
  228. assert.equal(code, 'KeyZ')
  229. assert.equal(keyCode, 90)
  230. assert.equal(shiftKey, true)
  231. assert.equal(ctrlKey, true)
  232. assert.equal(altKey, false)
  233. done()
  234. })
  235. w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z'})
  236. w.webContents.sendInputEvent({type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl']})
  237. })
  238. })
  239. })