Add some tests for "sandbox" option
This commit is contained in:
parent
a64978b812
commit
47fd41715f
3 changed files with 282 additions and 0 deletions
|
@ -16,6 +16,7 @@ const ipcRenderer = require('electron').ipcRenderer
|
|||
const BrowserWindow = remote.require('electron').BrowserWindow
|
||||
|
||||
const isCI = remote.getGlobal('isCi')
|
||||
const {protocol} = remote
|
||||
|
||||
describe('browser-window module', function () {
|
||||
var fixtures = path.resolve(__dirname, 'fixtures')
|
||||
|
@ -572,6 +573,198 @@ describe('browser-window module', function () {
|
|||
w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('"sandbox" option', function () {
|
||||
function waitForEvents (emitter, events, callback) {
|
||||
let count = events.length
|
||||
for (let event of events) {
|
||||
emitter.once(event, () => {
|
||||
if (!--count) callback()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const preload = path.join(fixtures, 'module', 'preload-sandbox.js')
|
||||
|
||||
// http protocol to simulate accessing a another domain. this is required
|
||||
// because the code paths for cross domain popups is different.
|
||||
function crossDomainHandler (request, callback) {
|
||||
callback({
|
||||
mimeType: 'text/html',
|
||||
data: `<html><body><h1>${request.url}</h1></body></html>`
|
||||
})
|
||||
}
|
||||
|
||||
before(function (done) {
|
||||
protocol.interceptStringProtocol('http', crossDomainHandler, function () {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
after(function (done) {
|
||||
protocol.uninterceptProtocol('http', function () {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('exposes ipcRenderer to preload script', function (done) {
|
||||
ipcMain.once('answer', function (event, test) {
|
||||
assert.equal(test, 'preload')
|
||||
done()
|
||||
})
|
||||
w.destroy()
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
sandbox: true,
|
||||
preload: preload
|
||||
}
|
||||
})
|
||||
w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html'))
|
||||
})
|
||||
|
||||
it('exposes "exit" event to preload script', function (done) {
|
||||
w.destroy()
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
sandbox: true,
|
||||
preload: preload
|
||||
}
|
||||
})
|
||||
let htmlPath = path.join(fixtures, 'api', 'sandbox.html?exit-event')
|
||||
const pageUrl = 'file://' + htmlPath
|
||||
w.loadURL(pageUrl)
|
||||
ipcMain.once('answer', function (event, url) {
|
||||
let expectedUrl = pageUrl
|
||||
if (process.platform === 'win32') {
|
||||
expectedUrl = 'file:///' + htmlPath.replace(/\\/g, '/')
|
||||
}
|
||||
assert.equal(url, expectedUrl)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should open windows in same domain with cross-scripting enabled', function (done) {
|
||||
w.destroy()
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
sandbox: true,
|
||||
preload: preload
|
||||
}
|
||||
})
|
||||
let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open')
|
||||
const pageUrl = 'file://' + htmlPath
|
||||
w.loadURL(pageUrl)
|
||||
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
|
||||
let expectedUrl = pageUrl
|
||||
if (process.platform === 'win32') {
|
||||
expectedUrl = 'file:///' + htmlPath.replace(/\\/g, '/')
|
||||
}
|
||||
assert.equal(url, expectedUrl)
|
||||
assert.equal(frameName, 'popup!')
|
||||
assert.equal(options.x, 50)
|
||||
assert.equal(options.y, 60)
|
||||
assert.equal(options.width, 500)
|
||||
assert.equal(options.height, 600)
|
||||
ipcMain.once('answer', function (event, html) {
|
||||
assert.equal(html, '<h1>scripting from opener</h1>')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should open windows in another domain with cross-scripting disabled', function (done) {
|
||||
w.destroy()
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
sandbox: true,
|
||||
preload: preload
|
||||
}
|
||||
})
|
||||
let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open-external')
|
||||
const pageUrl = 'file://' + htmlPath
|
||||
w.loadURL(pageUrl)
|
||||
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
|
||||
assert.equal(url, 'http://www.google.com/#q=electron')
|
||||
assert.equal(options.x, 55)
|
||||
assert.equal(options.y, 65)
|
||||
assert.equal(options.width, 505)
|
||||
assert.equal(options.height, 605)
|
||||
ipcMain.once('child-loaded', function (event, openerIsNull, html) {
|
||||
assert(openerIsNull)
|
||||
assert.equal(html, '<h1>http://www.google.com/#q=electron</h1>')
|
||||
ipcMain.once('answer', function (event, exceptionMessage) {
|
||||
assert(/Blocked a frame with origin/.test(exceptionMessage))
|
||||
done()
|
||||
})
|
||||
w.webContents.send('child-loaded')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should set ipc event sender correctly', function (done) {
|
||||
w.destroy()
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
sandbox: true,
|
||||
preload: preload
|
||||
}
|
||||
})
|
||||
let htmlPath = path.join(fixtures, 'api', 'sandbox.html?verify-ipc-sender')
|
||||
const pageUrl = 'file://' + htmlPath
|
||||
w.loadURL(pageUrl)
|
||||
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
|
||||
let parentWc = w.webContents
|
||||
let childWc = options.webContents
|
||||
assert.notEqual(parentWc, childWc)
|
||||
ipcMain.once('parent-ready', function (event) {
|
||||
assert.equal(parentWc, event.sender)
|
||||
parentWc.send('verified')
|
||||
})
|
||||
ipcMain.once('child-ready', function (event) {
|
||||
assert.equal(childWc, event.sender)
|
||||
childWc.send('verified')
|
||||
})
|
||||
waitForEvents(ipcMain, [
|
||||
'parent-answer',
|
||||
'child-answer'
|
||||
], done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('event handling', function () {
|
||||
it('works for window events', function (done) {
|
||||
waitForEvents(w, [
|
||||
'page-title-updated'
|
||||
], done)
|
||||
w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?window-events'))
|
||||
})
|
||||
|
||||
it('works for web contents events', function (done) {
|
||||
waitForEvents(w.webContents, [
|
||||
'did-navigate',
|
||||
'did-fail-load',
|
||||
'did-stop-loading'
|
||||
], done)
|
||||
w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-stop'))
|
||||
waitForEvents(w.webContents, [
|
||||
'did-finish-load',
|
||||
'did-frame-finish-load',
|
||||
'did-navigate-in-page',
|
||||
'will-navigate',
|
||||
'did-start-loading',
|
||||
'did-stop-loading',
|
||||
'did-frame-finish-load',
|
||||
'dom-ready'
|
||||
], done)
|
||||
w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-events'))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('beforeunload handler', function () {
|
||||
|
|
76
spec/fixtures/api/sandbox.html
vendored
Normal file
76
spec/fixtures/api/sandbox.html
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
<html>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
if (window.opener) {
|
||||
window.callback = function() {
|
||||
opener.require('electron').ipcRenderer.send('answer', document.body.innerHTML)
|
||||
};
|
||||
} else {
|
||||
const {ipcRenderer} = require('electron')
|
||||
const tests = {
|
||||
'window-events': () => {
|
||||
document.title = 'changed'
|
||||
},
|
||||
'webcontents-stop': () => {
|
||||
stop()
|
||||
},
|
||||
'webcontents-events': () => {
|
||||
addEventListener('load', () => {
|
||||
location.hash = 'in-page-navigate'
|
||||
setTimeout(() => {
|
||||
location.reload()
|
||||
}, 50)
|
||||
})
|
||||
},
|
||||
'exit-event': () => {
|
||||
process.on('exit', () => {
|
||||
ipcRenderer.send('answer', location.href)
|
||||
})
|
||||
location.assign('http://www.google.com')
|
||||
},
|
||||
'window-open': () => {
|
||||
addEventListener('load', () => {
|
||||
popup = open(window.location.href, 'popup!', 'top=60,left=50,width=500,height=600')
|
||||
popup.addEventListener('DOMContentLoaded', () => {
|
||||
popup.document.write('<h1>scripting from opener</h1>')
|
||||
popup.callback()
|
||||
}, false)
|
||||
})
|
||||
},
|
||||
'window-open-external': () => {
|
||||
addEventListener('load', () => {
|
||||
ipcRenderer.once('child-loaded', (e) => {
|
||||
try {
|
||||
let childDoc = popup.document
|
||||
} catch (e) {
|
||||
ipcRenderer.send('answer', e.message)
|
||||
}
|
||||
})
|
||||
popup = open('http://www.google.com/#q=electron', '', 'top=65,left=55,width=505,height=605')
|
||||
})
|
||||
},
|
||||
'verify-ipc-sender': () => {
|
||||
popup = open()
|
||||
ipcRenderer.once('verified', () => {
|
||||
ipcRenderer.send('parent-answer')
|
||||
})
|
||||
popup.ipcRenderer.once('verified', () => {
|
||||
popup.ipcRenderer.send('child-answer')
|
||||
})
|
||||
setTimeout(() => {
|
||||
ipcRenderer.send('parent-ready')
|
||||
popup.ipcRenderer.send('child-ready')
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('unload', () => {
|
||||
if (window.popup)
|
||||
popup.close()
|
||||
}, false)
|
||||
|
||||
let [,test] = window.location.href.split('?')
|
||||
if (tests.hasOwnProperty(test))
|
||||
tests[test]()
|
||||
}
|
||||
</script>
|
||||
</html>
|
13
spec/fixtures/module/preload-sandbox.js
vendored
Normal file
13
spec/fixtures/module/preload-sandbox.js
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
(function () {
|
||||
const {ipcRenderer} = require('electron')
|
||||
window.ipcRenderer = ipcRenderer
|
||||
if (location.protocol === 'file:') {
|
||||
window.test = 'preload'
|
||||
window.require = require
|
||||
window.process = process
|
||||
} else if (location.href !== 'about:blank') {
|
||||
addEventListener('DOMContentLoaded', () => {
|
||||
ipcRenderer.send('child-loaded', window.opener == null, document.body.innerHTML)
|
||||
}, false)
|
||||
}
|
||||
})()
|
Loading…
Reference in a new issue