api-browser-view-spec.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. 'use strict'
  2. const assert = require('assert')
  3. const chai = require('chai')
  4. const ChildProcess = require('child_process')
  5. const dirtyChai = require('dirty-chai')
  6. const path = require('path')
  7. const { emittedOnce } = require('./events-helpers')
  8. const { closeWindow } = require('./window-helpers')
  9. const { remote } = require('electron')
  10. const { BrowserView, BrowserWindow } = remote
  11. const { expect } = chai
  12. chai.use(dirtyChai)
  13. describe('BrowserView module', () => {
  14. const fixtures = path.resolve(__dirname, 'fixtures')
  15. let w = null
  16. let view = null
  17. beforeEach(() => {
  18. w = new BrowserWindow({
  19. show: false,
  20. width: 400,
  21. height: 400,
  22. webPreferences: {
  23. backgroundThrottling: false
  24. }
  25. })
  26. })
  27. afterEach(() => {
  28. if (view) {
  29. view.destroy()
  30. view = null
  31. }
  32. return closeWindow(w).then(() => { w = null })
  33. })
  34. describe('BrowserView.destroy()', () => {
  35. it('does not throw', () => {
  36. view = new BrowserView()
  37. view.destroy()
  38. })
  39. })
  40. describe('BrowserView.isDestroyed()', () => {
  41. it('returns correct value', () => {
  42. view = new BrowserView()
  43. expect(view.isDestroyed()).to.be.false()
  44. view.destroy()
  45. expect(view.isDestroyed()).to.be.true()
  46. })
  47. })
  48. describe('BrowserView.setBackgroundColor()', () => {
  49. it('does not throw for valid args', () => {
  50. view = new BrowserView()
  51. view.setBackgroundColor('#000')
  52. })
  53. it('throws for invalid args', () => {
  54. view = new BrowserView()
  55. expect(() => {
  56. view.setBackgroundColor(null)
  57. }).to.throw(/conversion failure/)
  58. })
  59. })
  60. describe('BrowserView.setAutoResize()', () => {
  61. it('does not throw for valid args', () => {
  62. view = new BrowserView()
  63. view.setAutoResize({})
  64. view.setAutoResize({ width: true, height: false })
  65. })
  66. it('throws for invalid args', () => {
  67. view = new BrowserView()
  68. expect(() => {
  69. view.setAutoResize(null)
  70. }).to.throw(/conversion failure/)
  71. })
  72. })
  73. describe('BrowserView.setBounds()', () => {
  74. it('does not throw for valid args', () => {
  75. view = new BrowserView()
  76. view.setBounds({ x: 0, y: 0, width: 1, height: 1 })
  77. })
  78. it('throws for invalid args', () => {
  79. view = new BrowserView()
  80. expect(() => {
  81. view.setBounds(null)
  82. }).to.throw(/conversion failure/)
  83. expect(() => {
  84. view.setBounds({})
  85. }).to.throw(/conversion failure/)
  86. })
  87. })
  88. describe('BrowserWindow.setBrowserView()', () => {
  89. it('does not throw for valid args', () => {
  90. view = new BrowserView()
  91. w.setBrowserView(view)
  92. })
  93. it('does not throw if called multiple times with same view', () => {
  94. view = new BrowserView()
  95. w.setBrowserView(view)
  96. w.setBrowserView(view)
  97. w.setBrowserView(view)
  98. })
  99. })
  100. describe('BrowserWindow.getBrowserView()', () => {
  101. it('returns the set view', () => {
  102. view = new BrowserView()
  103. w.setBrowserView(view)
  104. expect(view.id).to.not.be.null()
  105. const view2 = w.getBrowserView()
  106. expect(view2.webContents.id).to.equal(view.webContents.id)
  107. })
  108. it('returns null if none is set', () => {
  109. const view = w.getBrowserView()
  110. expect(view).to.be.null()
  111. })
  112. })
  113. describe('BrowserView.webContents.getOwnerBrowserWindow()', () => {
  114. it('points to owning window', () => {
  115. view = new BrowserView()
  116. expect(view.webContents.getOwnerBrowserWindow()).to.be.null()
  117. w.setBrowserView(view)
  118. expect(view.webContents.getOwnerBrowserWindow()).to.equal(w)
  119. w.setBrowserView(null)
  120. expect(view.webContents.getOwnerBrowserWindow()).to.be.null()
  121. })
  122. })
  123. describe('BrowserView.fromId()', () => {
  124. it('returns the view with given id', () => {
  125. view = new BrowserView()
  126. w.setBrowserView(view)
  127. expect(view.id).to.not.be.null()
  128. const view2 = BrowserView.fromId(view.id)
  129. expect(view2.webContents.id).to.equal(view.webContents.id)
  130. })
  131. })
  132. describe('BrowserView.fromWebContents()', () => {
  133. it('returns the view with given id', () => {
  134. view = new BrowserView()
  135. w.setBrowserView(view)
  136. expect(view.id).to.not.be.null()
  137. const view2 = BrowserView.fromWebContents(view.webContents)
  138. expect(view2.webContents.id).to.equal(view.webContents.id)
  139. })
  140. })
  141. describe('BrowserView.getAllViews()', () => {
  142. it('returns all views', () => {
  143. view = new BrowserView()
  144. w.setBrowserView(view)
  145. expect(view.id).to.not.be.null()
  146. const views = BrowserView.getAllViews()
  147. expect(views).to.be.an('array').that.has.lengthOf(1)
  148. expect(views[0].webContents.id).to.equal(view.webContents.id)
  149. })
  150. })
  151. describe('new BrowserView()', () => {
  152. it('does not crash on exit', async () => {
  153. const appPath = path.join(fixtures, 'api', 'leak-exit-browserview.js')
  154. const electronPath = remote.getGlobal('process').execPath
  155. const appProcess = ChildProcess.spawn(electronPath, [appPath])
  156. const [code] = await emittedOnce(appProcess, 'close')
  157. expect(code).to.equal(0)
  158. })
  159. })
  160. describe('window.open()', () => {
  161. it('works in BrowserView', (done) => {
  162. view = new BrowserView()
  163. w.setBrowserView(view)
  164. view.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures) => {
  165. e.preventDefault()
  166. assert.strictEqual(url, 'http://host/')
  167. assert.strictEqual(frameName, 'host')
  168. assert.strictEqual(additionalFeatures[0], 'this-is-not-a-standard-feature')
  169. done()
  170. })
  171. view.webContents.loadFile(path.join(fixtures, 'pages', 'window-open.html'))
  172. })
  173. })
  174. })