|
@@ -1,6 +1,8 @@
|
|
|
import { contextBridge, BrowserWindow, ipcMain } from 'electron'
|
|
|
import { expect } from 'chai'
|
|
|
import * as fs from 'fs-extra'
|
|
|
+import * as http from 'http'
|
|
|
+import { AddressInfo } from 'net'
|
|
|
import * as os from 'os'
|
|
|
import * as path from 'path'
|
|
|
|
|
@@ -12,6 +14,20 @@ const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'context-bridge'
|
|
|
describe('contextBridge', () => {
|
|
|
let w: BrowserWindow
|
|
|
let dir: string
|
|
|
+ let server: http.Server
|
|
|
+
|
|
|
+ before(async () => {
|
|
|
+ server = http.createServer((req, res) => {
|
|
|
+ res.setHeader('Content-Type', 'text/html')
|
|
|
+ res.end('')
|
|
|
+ })
|
|
|
+ await new Promise(resolve => server.listen(0, resolve))
|
|
|
+ })
|
|
|
+
|
|
|
+ after(async () => {
|
|
|
+ if (server) await new Promise(resolve => server.close(resolve))
|
|
|
+ server = null as any
|
|
|
+ })
|
|
|
|
|
|
afterEach(async () => {
|
|
|
await closeWindow(w)
|
|
@@ -64,7 +80,7 @@ describe('contextBridge', () => {
|
|
|
preload: path.resolve(tmpDir, 'preload.js')
|
|
|
}
|
|
|
})
|
|
|
- await w.loadFile(path.resolve(fixturesPath, 'empty.html'))
|
|
|
+ await w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`)
|
|
|
}
|
|
|
|
|
|
const callWithBindings = async (fn: Function) => {
|
|
@@ -503,7 +519,28 @@ describe('contextBridge', () => {
|
|
|
expect(info.objectCount).to.equal(6)
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ if (useSandbox) {
|
|
|
+ it('should not leak the global hold on methods sent across contexts when reloading a sandboxed renderer', async () => {
|
|
|
+ await makeBindingWindow(() => {
|
|
|
+ require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()))
|
|
|
+ contextBridge.exposeInMainWorld('example', {
|
|
|
+ getFunction: () => () => 123
|
|
|
+ })
|
|
|
+ require('electron').ipcRenderer.send('window-ready-for-tasking')
|
|
|
+ })
|
|
|
+ const loadPromise = emittedOnce(ipcMain, 'window-ready-for-tasking')
|
|
|
+ expect((await getGCInfo()).functionCount).to.equal(1)
|
|
|
+ await callWithBindings((root: any) => {
|
|
|
+ root.location.reload()
|
|
|
+ })
|
|
|
+ await loadPromise
|
|
|
+ // If this is ever "2" it means we leaked the exposed function and
|
|
|
+ // therefore the entire context after a reload
|
|
|
+ expect((await getGCInfo()).functionCount).to.equal(1)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
it('it should not let you overwrite existing exposed things', async () => {
|
|
|
await makeBindingWindow(() => {
|
|
|
let threw = false
|