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:
parent
3a79eacb6f
commit
32158ca5dd
5 changed files with 63 additions and 59 deletions
|
@ -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`)
|
||||||
assert.deepEqual(data, expectedContextData)
|
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
|
||||||
done()
|
assert.deepEqual(data, expectedContextData)
|
||||||
})
|
|
||||||
w.loadURL(`file://${fixtures}/api/isolated.html`)
|
|
||||||
})
|
})
|
||||||
it('recreates the contexts on reload', (done) => {
|
it('recreates the contexts on reload', async () => {
|
||||||
w.webContents.once('did-finish-load', () => {
|
iw.loadURL(`file://${fixtures}/api/isolated.html`)
|
||||||
ipcMain.once('isolated-world', (event, data) => {
|
await emittedOnce(iw.webContents, 'did-finish-load')
|
||||||
assert.deepEqual(data, expectedContextData)
|
iw.webContents.reload()
|
||||||
done()
|
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
|
||||||
})
|
assert.deepEqual(data, expectedContextData)
|
||||||
w.webContents.reload()
|
|
||||||
})
|
|
||||||
w.loadURL(`file://${fixtures}/api/isolated.html`)
|
|
||||||
})
|
})
|
||||||
it('enables context isolation on child windows', (done) => {
|
it('enables context isolation on child windows', async () => {
|
||||||
app.once('browser-window-created', (event, window) => {
|
iw.loadURL(`file://${fixtures}/pages/window-open.html`)
|
||||||
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
|
const [, window] = await emittedOnce(app, 'browser-window-created')
|
||||||
done()
|
assert.ok(window.webContents.getLastWebPreferences().contextIsolation)
|
||||||
})
|
|
||||||
w.loadURL(`file://${fixtures}/pages/window-open.html`)
|
|
||||||
})
|
})
|
||||||
it('separates the page context from the Electron/preload context with sandbox on', (done) => {
|
it('separates the page context from the Electron/preload context with sandbox on', async () => {
|
||||||
ipcMain.once('isolated-sandbox-world', (event, data) => {
|
ws.loadURL(`file://${fixtures}/api/isolated.html`)
|
||||||
assert.deepEqual(data, expectedContextData)
|
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
|
||||||
done()
|
assert.deepEqual(data, expectedContextData)
|
||||||
})
|
|
||||||
w.loadURL(`file://${fixtures}/api/isolated.html`)
|
|
||||||
})
|
})
|
||||||
it('recreates the contexts on reload with sandbox on', (done) => {
|
it('recreates the contexts on reload with sandbox on', async () => {
|
||||||
w.webContents.once('did-finish-load', () => {
|
ws.loadURL(`file://${fixtures}/api/isolated.html`)
|
||||||
ipcMain.once('isolated-sandbox-world', (event, data) => {
|
await emittedOnce(ws.webContents, 'did-finish-load')
|
||||||
assert.deepEqual(data, expectedContextData)
|
ws.webContents.reload()
|
||||||
done()
|
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
|
||||||
})
|
assert.deepEqual(data, expectedContextData)
|
||||||
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, '')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
6
spec/fixtures/api/isolated-fetch-preload.js
vendored
Normal file
6
spec/fixtures/api/isolated-fetch-preload.js
vendored
Normal 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)
|
||||||
|
})
|
18
spec/fixtures/api/isolated-preload.js
vendored
18
spec/fixtures/api/isolated-preload.js
vendored
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
2
spec/fixtures/api/isolated.html
vendored
2
spec/fixtures/api/isolated.html
vendored
|
@ -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,
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Reference in a new issue