api-browser-view-spec.ts 7.2 KB

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