chore: refactor context isolation spec (#14394)

* spec: refactor BrowserWindow module contextIsolation option

* spec: check for serialzation in isolated renderers separately
This commit is contained in:
Robo 2018-09-01 02:21:29 +05:30 committed by Samuel Attard
parent 3a79eacb6f
commit 32158ca5dd
5 changed files with 63 additions and 59 deletions

View file

@ -23,6 +23,7 @@ chai.use(dirtyChai)
describe('BrowserWindow module', () => { describe('BrowserWindow module', () => {
const fixtures = path.resolve(__dirname, 'fixtures') const fixtures = path.resolve(__dirname, 'fixtures')
let w = null let w = null
let iw = null
let ws = null let ws = null
let server let server
let postData let postData
@ -3234,10 +3235,10 @@ describe('BrowserWindow module', () => {
typeofRequire: 'function', typeofRequire: 'function',
typeofProcess: 'object', typeofProcess: 'object',
typeofArrayPush: 'function', typeofArrayPush: 'function',
typeofFunctionApply: 'function' typeofFunctionApply: 'function',
typeofPreloadExecuteJavaScriptProperty: 'undefined'
}, },
pageContext: { pageContext: {
openedLocation: '',
preloadProperty: 'undefined', preloadProperty: 'undefined',
pageProperty: 'string', pageProperty: 'string',
typeofRequire: 'undefined', typeofRequire: 'undefined',
@ -3250,8 +3251,8 @@ describe('BrowserWindow module', () => {
} }
beforeEach(() => { beforeEach(() => {
if (w != null) w.destroy() if (iw != null) iw.destroy()
w = new BrowserWindow({ iw = new BrowserWindow({
show: false, show: false,
webPreferences: { webPreferences: {
contextIsolation: true, contextIsolation: true,
@ -3270,49 +3271,62 @@ describe('BrowserWindow module', () => {
}) })
afterEach(() => { afterEach(() => {
if (iw != null) iw.destroy()
if (ws != null) ws.destroy() if (ws != null) ws.destroy()
}) })
it('separates the page context from the Electron/preload context', (done) => { it('separates the page context from the Electron/preload context', async () => {
ipcMain.once('isolated-world', (event, data) => { iw.loadURL(`file://${fixtures}/api/isolated.html`)
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
assert.deepEqual(data, expectedContextData) assert.deepEqual(data, expectedContextData)
done()
}) })
w.loadURL(`file://${fixtures}/api/isolated.html`) it('recreates the contexts on reload', async () => {
}) iw.loadURL(`file://${fixtures}/api/isolated.html`)
it('recreates the contexts on reload', (done) => { await emittedOnce(iw.webContents, 'did-finish-load')
w.webContents.once('did-finish-load', () => { iw.webContents.reload()
ipcMain.once('isolated-world', (event, data) => { const [, data] = await emittedOnce(ipcMain, 'isolated-world')
assert.deepEqual(data, expectedContextData) assert.deepEqual(data, expectedContextData)
done()
}) })
w.webContents.reload() it('enables context isolation on child windows', async () => {
iw.loadURL(`file://${fixtures}/pages/window-open.html`)
const [, window] = await emittedOnce(app, 'browser-window-created')
assert.ok(window.webContents.getLastWebPreferences().contextIsolation)
}) })
w.loadURL(`file://${fixtures}/api/isolated.html`) it('separates the page context from the Electron/preload context with sandbox on', async () => {
}) ws.loadURL(`file://${fixtures}/api/isolated.html`)
it('enables context isolation on child windows', (done) => { const [, data] = await emittedOnce(ipcMain, 'isolated-world')
app.once('browser-window-created', (event, window) => {
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
done()
})
w.loadURL(`file://${fixtures}/pages/window-open.html`)
})
it('separates the page context from the Electron/preload context with sandbox on', (done) => {
ipcMain.once('isolated-sandbox-world', (event, data) => {
assert.deepEqual(data, expectedContextData) assert.deepEqual(data, expectedContextData)
done()
}) })
w.loadURL(`file://${fixtures}/api/isolated.html`) it('recreates the contexts on reload with sandbox on', async () => {
}) ws.loadURL(`file://${fixtures}/api/isolated.html`)
it('recreates the contexts on reload with sandbox on', (done) => { await emittedOnce(ws.webContents, 'did-finish-load')
w.webContents.once('did-finish-load', () => { ws.webContents.reload()
ipcMain.once('isolated-sandbox-world', (event, data) => { const [, data] = await emittedOnce(ipcMain, 'isolated-world')
assert.deepEqual(data, expectedContextData) assert.deepEqual(data, expectedContextData)
done()
}) })
w.webContents.reload() it('supports fetch api', async () => {
const fetchWindow = new BrowserWindow({
show: false,
webPreferences: {
contextIsolation: true,
preload: path.join(fixtures, 'api', 'isolated-fetch-preload.js')
}
}) })
w.loadURL(`file://${fixtures}/api/isolated.html`) fetchWindow.loadURL('about:blank')
const [, error] = await emittedOnce(ipcMain, 'isolated-fetch-error')
fetchWindow.destroy()
assert.equal(error, 'Failed to fetch')
})
it('doesn\'t break ipc serialization', async () => {
iw.loadURL('about:blank')
iw.webContents.executeJavaScript(`
const opened = window.open()
openedLocation = opened.location
opened.close()
window.postMessage({openedLocation}, '*')
`)
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
assert.equal(data.pageContext.openedLocation, '')
}) })
}) })

View file

@ -0,0 +1,6 @@
const {ipcRenderer} = require('electron')
// Ensure fetch works from isolated world origin
fetch('https://localhost:1234').catch(err => {
ipcRenderer.send('isolated-fetch-error', err.message)
})

View file

@ -1,7 +1,3 @@
// Ensure fetch works from isolated world origin
fetch('http://localhost:1234')
fetch('https://localhost:1234')
const {ipcRenderer, webFrame} = require('electron') const {ipcRenderer, webFrame} = require('electron')
window.foo = 3 window.foo = 3
@ -16,18 +12,8 @@ window.addEventListener('message', (event) => {
typeofRequire: typeof require, typeofRequire: typeof require,
typeofProcess: typeof process, typeofProcess: typeof process,
typeofArrayPush: typeof Array.prototype.push, typeofArrayPush: typeof Array.prototype.push,
typeofFunctionApply: typeof Function.prototype.apply typeofFunctionApply: typeof Function.prototype.apply,
}, typeofPreloadExecuteJavaScriptProperty: typeof window.preloadExecuteJavaScriptProperty
pageContext: event.data
})
ipcRenderer.send('isolated-sandbox-world', {
preloadContext: {
preloadProperty: typeof window.foo,
pageProperty: typeof window.hello,
typeofRequire: typeof require,
typeofProcess: typeof process,
typeofArrayPush: typeof Array.prototype.push,
typeofFunctionApply: typeof Function.prototype.apply
}, },
pageContext: event.data pageContext: event.data
}) })

View file

@ -9,11 +9,9 @@
Function.prototype.apply = true Function.prototype.apply = true
const opened = window.open() const opened = window.open()
const openedLocation = opened.location
opened.close() opened.close()
window.postMessage({ window.postMessage({
openedLocation,
preloadProperty: typeof window.foo, preloadProperty: typeof window.foo,
pageProperty: typeof window.hello, pageProperty: typeof window.hello,
typeofRequire: typeof require, typeofRequire: typeof require,

View file

@ -535,10 +535,10 @@ describe('<webview> tag', function () {
typeofRequire: 'function', typeofRequire: 'function',
typeofProcess: 'object', typeofProcess: 'object',
typeofArrayPush: 'function', typeofArrayPush: 'function',
typeofFunctionApply: 'function' typeofFunctionApply: 'function',
typeofPreloadExecuteJavaScriptProperty: 'undefined'
}, },
pageContext: { pageContext: {
openedLocation: '',
preloadProperty: 'undefined', preloadProperty: 'undefined',
pageProperty: 'string', pageProperty: 'string',
typeofRequire: 'undefined', typeofRequire: 'undefined',