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 BrowserWindow = remote.require('electron').BrowserWindow
|
||||||
|
|
||||||
const isCI = remote.getGlobal('isCi')
|
const isCI = remote.getGlobal('isCi')
|
||||||
|
const {protocol} = remote
|
||||||
|
|
||||||
describe('browser-window module', function () {
|
describe('browser-window module', function () {
|
||||||
var fixtures = path.resolve(__dirname, 'fixtures')
|
var fixtures = path.resolve(__dirname, 'fixtures')
|
||||||
|
@ -572,6 +573,198 @@ describe('browser-window module', function () {
|
||||||
w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html'))
|
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 () {
|
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