mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
Merge branch 'master' into native-window-open
This commit is contained in:
@@ -137,6 +137,16 @@ describe('app module', function () {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('closes all windows', function (done) {
|
||||
var appPath = path.join(__dirname, 'fixtures', 'api', 'exit-closes-all-windows-app')
|
||||
var electronPath = remote.getGlobal('process').execPath
|
||||
appProcess = ChildProcess.spawn(electronPath, [appPath])
|
||||
appProcess.on('close', function (code) {
|
||||
assert.equal(code, 123)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('app.relaunch', function () {
|
||||
|
||||
92
spec/api-browser-view-spec.js
Normal file
92
spec/api-browser-view-spec.js
Normal file
@@ -0,0 +1,92 @@
|
||||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const {closeWindow} = require('./window-helpers')
|
||||
|
||||
const {remote} = require('electron')
|
||||
const {BrowserView, BrowserWindow} = remote
|
||||
|
||||
describe('View module', function () {
|
||||
var w = null
|
||||
var view = null
|
||||
|
||||
beforeEach(function () {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
width: 400,
|
||||
height: 400,
|
||||
webPreferences: {
|
||||
backgroundThrottling: false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
if (view) {
|
||||
view.destroy()
|
||||
view = null
|
||||
}
|
||||
|
||||
return closeWindow(w).then(function () { w = null })
|
||||
})
|
||||
|
||||
describe('BrowserView.setBackgroundColor()', function () {
|
||||
it('does not throw for valid args', function () {
|
||||
view = new BrowserView()
|
||||
view.setBackgroundColor('#000')
|
||||
})
|
||||
|
||||
it('throws for invalid args', function () {
|
||||
view = new BrowserView()
|
||||
assert.throws(function () {
|
||||
view.setBackgroundColor(null)
|
||||
}, /conversion failure/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('BrowserView.setAutoResize()', function () {
|
||||
it('does not throw for valid args', function () {
|
||||
view = new BrowserView()
|
||||
view.setAutoResize({})
|
||||
view.setAutoResize({ width: true, height: false })
|
||||
})
|
||||
|
||||
it('throws for invalid args', function () {
|
||||
view = new BrowserView()
|
||||
assert.throws(function () {
|
||||
view.setAutoResize(null)
|
||||
}, /conversion failure/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('BrowserView.setBounds()', function () {
|
||||
it('does not throw for valid args', function () {
|
||||
view = new BrowserView()
|
||||
view.setBounds({ x: 0, y: 0, width: 1, height: 1 })
|
||||
})
|
||||
|
||||
it('throws for invalid args', function () {
|
||||
view = new BrowserView()
|
||||
assert.throws(function () {
|
||||
view.setBounds(null)
|
||||
}, /conversion failure/)
|
||||
assert.throws(function () {
|
||||
view.setBounds({})
|
||||
}, /conversion failure/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('BrowserWindow.setBrowserView()', function () {
|
||||
it('does not throw for valid args', function () {
|
||||
view = new BrowserView()
|
||||
w.setBrowserView(view)
|
||||
})
|
||||
|
||||
it('does not throw if called multiple times with same view', function () {
|
||||
view = new BrowserView()
|
||||
w.setBrowserView(view)
|
||||
w.setBrowserView(view)
|
||||
w.setBrowserView(view)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -15,24 +15,32 @@ describe('crashReporter module', function () {
|
||||
if (process.mas) {
|
||||
return
|
||||
}
|
||||
|
||||
var originalTempDirectory = null
|
||||
var tempDirectory = null
|
||||
|
||||
before(function () {
|
||||
tempDirectory = temp.mkdirSync('electronCrashReporterSpec-')
|
||||
originalTempDirectory = app.getPath('temp')
|
||||
app.setPath('temp', tempDirectory)
|
||||
})
|
||||
|
||||
after(function () {
|
||||
app.setPath('temp', originalTempDirectory)
|
||||
})
|
||||
|
||||
var fixtures = path.resolve(__dirname, 'fixtures')
|
||||
const generateSpecs = (description, browserWindowOpts) => {
|
||||
describe(description, function () {
|
||||
var w = null
|
||||
var originalTempDirectory = null
|
||||
var tempDirectory = null
|
||||
|
||||
beforeEach(function () {
|
||||
w = new BrowserWindow(Object.assign({
|
||||
show: false
|
||||
}, browserWindowOpts))
|
||||
tempDirectory = temp.mkdirSync('electronCrashReporterSpec-')
|
||||
originalTempDirectory = app.getPath('temp')
|
||||
app.setPath('temp', tempDirectory)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
app.setPath('temp', originalTempDirectory)
|
||||
return closeWindow(w).then(function () { w = null })
|
||||
})
|
||||
|
||||
@@ -77,13 +85,15 @@ describe('crashReporter module', function () {
|
||||
it('should not send minidump if uploadToServer is false', function (done) {
|
||||
this.timeout(120000)
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
crashReporter.setUploadToServer(false)
|
||||
}
|
||||
|
||||
let server
|
||||
let dumpFile
|
||||
let crashesDir
|
||||
let crashesDir = crashReporter.getCrashesDirectory()
|
||||
const existingDumpFiles = new Set()
|
||||
if (process.platform === 'darwin') {
|
||||
// crashpad puts the dump files in the "completed" subdirectory
|
||||
crashesDir = path.join(crashesDir, 'completed')
|
||||
crashReporter.setUploadToServer(false)
|
||||
}
|
||||
const testDone = (uploaded) => {
|
||||
if (uploaded) {
|
||||
return done(new Error('fail'))
|
||||
@@ -93,7 +103,6 @@ describe('crashReporter module', function () {
|
||||
crashReporter.setUploadToServer(true)
|
||||
}
|
||||
assert(fs.existsSync(dumpFile))
|
||||
fs.unlinkSync(dumpFile)
|
||||
done()
|
||||
}
|
||||
|
||||
@@ -103,7 +112,7 @@ describe('crashReporter module', function () {
|
||||
if (err) {
|
||||
return
|
||||
}
|
||||
const dumps = files.filter((file) => /\.dmp$/.test(file))
|
||||
const dumps = files.filter((file) => /\.dmp$/.test(file) && !existingDumpFiles.has(file))
|
||||
if (!dumps.length) {
|
||||
return
|
||||
}
|
||||
@@ -111,34 +120,17 @@ describe('crashReporter module', function () {
|
||||
dumpFile = path.join(crashesDir, dumps[0])
|
||||
clearInterval(pollInterval)
|
||||
// dump file should not be deleted when not uploading, so we wait
|
||||
// 500 ms and assert it still exists in `testDone`
|
||||
setTimeout(testDone, 500)
|
||||
// 1s and assert it still exists in `testDone`
|
||||
setTimeout(testDone, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
remote.ipcMain.once('set-crash-directory', (event, dir) => {
|
||||
if (process.platform === 'linux') {
|
||||
crashesDir = dir
|
||||
} else {
|
||||
crashesDir = crashReporter.getCrashesDirectory()
|
||||
if (process.platform === 'darwin') {
|
||||
// crashpad uses an extra subdirectory
|
||||
crashesDir = path.join(crashesDir, 'completed')
|
||||
}
|
||||
}
|
||||
|
||||
// Before starting, remove all dump files in the crash directory.
|
||||
// This is required because:
|
||||
// - mac crashpad not seem to allow changing the crash directory after
|
||||
// the first "start" call.
|
||||
// - Other tests in this suite may leave dumps there.
|
||||
// - We want to verify in `testDone` that a dump file is created and
|
||||
// not deleted.
|
||||
remote.ipcMain.once('list-existing-dumps', (event) => {
|
||||
fs.readdir(crashesDir, (err, files) => {
|
||||
if (!err) {
|
||||
for (const file of files) {
|
||||
if (/\.dmp$/.test(file)) {
|
||||
fs.unlinkSync(path.join(crashesDir, file))
|
||||
existingDumpFiles.add(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,20 @@ describe('dialog module', () => {
|
||||
}, /Error processing argument at index 1/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('showCertificateTrustDialog', () => {
|
||||
it('throws errors when the options are invalid', () => {
|
||||
assert.throws(() => {
|
||||
dialog.showCertificateTrustDialog()
|
||||
}, /options must be an object/)
|
||||
|
||||
assert.throws(() => {
|
||||
dialog.showCertificateTrustDialog({})
|
||||
}, /certificate must be an object/)
|
||||
|
||||
assert.throws(() => {
|
||||
dialog.showCertificateTrustDialog({certificate: {}, message: false})
|
||||
}, /message must be a string/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -175,8 +175,14 @@ describe('ipc module', function () {
|
||||
it('can change its properties', function () {
|
||||
var property = remote.require(path.join(fixtures, 'module', 'property.js'))
|
||||
assert.equal(property.property, 1127)
|
||||
|
||||
property.property = null
|
||||
assert.equal(property.property, null)
|
||||
property.property = undefined
|
||||
assert.equal(property.property, undefined)
|
||||
property.property = 1007
|
||||
assert.equal(property.property, 1007)
|
||||
|
||||
assert.equal(property.getFunctionProperty(), 'foo-browser')
|
||||
property.func.property = 'bar'
|
||||
assert.equal(property.getFunctionProperty(), 'bar-browser')
|
||||
@@ -199,6 +205,14 @@ describe('ipc module', function () {
|
||||
}, /setting error/)
|
||||
})
|
||||
|
||||
it('can set a remote property with a remote object', function () {
|
||||
const foo = remote.require(path.join(fixtures, 'module', 'remote-object-set.js'))
|
||||
|
||||
assert.doesNotThrow(function () {
|
||||
foo.bar = remote.getCurrentWindow()
|
||||
})
|
||||
})
|
||||
|
||||
it('can construct an object from its member', function () {
|
||||
var call = remote.require(path.join(fixtures, 'module', 'call.js'))
|
||||
var obj = new call.constructor()
|
||||
|
||||
@@ -26,22 +26,34 @@ const kOneKiloByte = 1024
|
||||
const kOneMegaByte = kOneKiloByte * kOneKiloByte
|
||||
|
||||
describe('net module', function () {
|
||||
describe('HTTP basics', function () {
|
||||
let server
|
||||
beforeEach(function (done) {
|
||||
server = http.createServer()
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
server.url = 'http://127.0.0.1:' + server.address().port
|
||||
done()
|
||||
let server
|
||||
const connections = new Set()
|
||||
|
||||
beforeEach(function (done) {
|
||||
server = http.createServer()
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
server.url = `http://127.0.0.1:${server.address().port}`
|
||||
done()
|
||||
})
|
||||
server.on('connection', (connection) => {
|
||||
connections.add(connection)
|
||||
connection.once('close', () => {
|
||||
connections.delete(connection)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
server.close(function () {
|
||||
})
|
||||
afterEach(function (done) {
|
||||
for (const connection of connections) {
|
||||
connection.destroy()
|
||||
}
|
||||
server.close(function () {
|
||||
server = null
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
describe('HTTP basics', function () {
|
||||
it('should be able to issue a basic GET request', function (done) {
|
||||
const requestUrl = '/requestUrl'
|
||||
server.on('request', function (request, response) {
|
||||
@@ -224,19 +236,7 @@ describe('net module', function () {
|
||||
})
|
||||
|
||||
describe('ClientRequest API', function () {
|
||||
let server
|
||||
beforeEach(function (done) {
|
||||
server = http.createServer()
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
server.url = 'http://127.0.0.1:' + server.address().port
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
server.close(function () {
|
||||
})
|
||||
server = null
|
||||
session.defaultSession.webRequest.onBeforeRequest(null)
|
||||
})
|
||||
|
||||
@@ -1363,21 +1363,8 @@ describe('net module', function () {
|
||||
urlRequest.end()
|
||||
})
|
||||
})
|
||||
|
||||
describe('IncomingMessage API', function () {
|
||||
let server
|
||||
beforeEach(function (done) {
|
||||
server = http.createServer()
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
server.url = 'http://127.0.0.1:' + server.address().port
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
server.close()
|
||||
server = null
|
||||
})
|
||||
|
||||
it('response object should implement the IncomingMessage API', function (done) {
|
||||
const requestUrl = '/requestUrl'
|
||||
const customHeaderName = 'Some-Custom-Header-Name'
|
||||
@@ -1544,21 +1531,8 @@ describe('net module', function () {
|
||||
urlRequest.end()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Stability and performance', function (done) {
|
||||
let server
|
||||
beforeEach(function (done) {
|
||||
server = http.createServer()
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
server.url = 'http://127.0.0.1:' + server.address().port
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
server.close()
|
||||
server = null
|
||||
})
|
||||
|
||||
it('should free unreferenced, never-started request objects without crash', function (done) {
|
||||
const requestUrl = '/requestUrl'
|
||||
ipcRenderer.once('api-net-spec-done', function () {
|
||||
@@ -1574,6 +1548,7 @@ describe('net module', function () {
|
||||
})
|
||||
`)
|
||||
})
|
||||
|
||||
it('should not collect on-going requests without crash', function (done) {
|
||||
const requestUrl = '/requestUrl'
|
||||
server.on('request', function (request, response) {
|
||||
@@ -1615,6 +1590,7 @@ describe('net module', function () {
|
||||
urlRequest.end()
|
||||
`)
|
||||
})
|
||||
|
||||
it('should collect unreferenced, ended requests without crash', function (done) {
|
||||
const requestUrl = '/requestUrl'
|
||||
server.on('request', function (request, response) {
|
||||
|
||||
@@ -6,20 +6,32 @@ const {TouchBarButton, TouchBarColorPicker, TouchBarGroup} = TouchBar
|
||||
const {TouchBarLabel, TouchBarPopover, TouchBarScrubber, TouchBarSegmentedControl, TouchBarSlider, TouchBarSpacer} = TouchBar
|
||||
|
||||
describe('TouchBar module', function () {
|
||||
it('throws an error when created without an items array', function () {
|
||||
it('throws an error when created without an options object', function () {
|
||||
assert.throws(() => {
|
||||
const touchBar = new TouchBar()
|
||||
touchBar.toString()
|
||||
}, /Must specify items array as first argument/)
|
||||
}, /Must specify options object as first argument/)
|
||||
})
|
||||
|
||||
it('throws an error when created with invalid items', function () {
|
||||
assert.throws(() => {
|
||||
const touchBar = new TouchBar([1, true, {}, []])
|
||||
const touchBar = new TouchBar({items: [1, true, {}, []]})
|
||||
touchBar.toString()
|
||||
}, /Each item must be an instance of TouchBarItem/)
|
||||
})
|
||||
|
||||
it('throws an error when an invalid escape item is set', function () {
|
||||
assert.throws(() => {
|
||||
const touchBar = new TouchBar({items: [], escapeItem: 'esc'})
|
||||
touchBar.toString()
|
||||
}, /Escape item must be an instance of TouchBarItem/)
|
||||
|
||||
assert.throws(() => {
|
||||
const touchBar = new TouchBar({items: []})
|
||||
touchBar.escapeItem = 'esc'
|
||||
}, /Escape item must be an instance of TouchBarItem/)
|
||||
})
|
||||
|
||||
describe('BrowserWindow behavior', function () {
|
||||
let window
|
||||
|
||||
@@ -55,10 +67,40 @@ describe('TouchBar module', function () {
|
||||
showArrowButtons: true
|
||||
})
|
||||
])
|
||||
const escapeButton = new TouchBarButton({
|
||||
label: 'foo'
|
||||
})
|
||||
window.setTouchBar(touchBar)
|
||||
touchBar.escapeItem = escapeButton
|
||||
label.label = 'baz'
|
||||
escapeButton.label = 'hello'
|
||||
window.setTouchBar()
|
||||
window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})]))
|
||||
touchBar.escapeItem = null
|
||||
})
|
||||
|
||||
it('calls the callback on the items when a window interaction event fires', function (done) {
|
||||
const button = new TouchBarButton({
|
||||
label: 'bar',
|
||||
click: () => {
|
||||
done()
|
||||
}
|
||||
})
|
||||
const touchBar = new TouchBar({items: [button]})
|
||||
window.setTouchBar(touchBar)
|
||||
window.emit('-touch-bar-interaction', {}, button.id)
|
||||
})
|
||||
|
||||
it('calls the callback on the escape item when a window interaction event fires', function (done) {
|
||||
const button = new TouchBarButton({
|
||||
label: 'bar',
|
||||
click: () => {
|
||||
done()
|
||||
}
|
||||
})
|
||||
const touchBar = new TouchBar({escapeItem: button})
|
||||
window.setTouchBar(touchBar)
|
||||
window.emit('-touch-bar-interaction', {}, button.id)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
2
spec/fixtures/api/crash.html
vendored
2
spec/fixtures/api/crash.html
vendored
@@ -17,7 +17,7 @@ crashReporter.start({
|
||||
}
|
||||
});
|
||||
if (!uploadToServer) {
|
||||
ipcRenderer.sendSync('set-crash-directory', crashReporter.getCrashesDirectory())
|
||||
ipcRenderer.sendSync('list-existing-dumps')
|
||||
}
|
||||
setImmediate(function() { process.crash(); });
|
||||
</script>
|
||||
|
||||
19
spec/fixtures/api/exit-closes-all-windows-app/main.js
vendored
Normal file
19
spec/fixtures/api/exit-closes-all-windows-app/main.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
const {app, BrowserWindow} = require('electron')
|
||||
|
||||
const windows = []
|
||||
|
||||
function createWindow (id) {
|
||||
const window = new BrowserWindow({show: false})
|
||||
window.loadURL(`data:,window${id}`)
|
||||
windows.push(window)
|
||||
}
|
||||
|
||||
app.once('ready', () => {
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
createWindow(i)
|
||||
}
|
||||
|
||||
setImmediate(function () {
|
||||
app.exit(123)
|
||||
})
|
||||
})
|
||||
4
spec/fixtures/api/exit-closes-all-windows-app/package.json
vendored
Normal file
4
spec/fixtures/api/exit-closes-all-windows-app/package.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "electron-exit-closes-all-windows",
|
||||
"main": "main.js"
|
||||
}
|
||||
11
spec/fixtures/module/remote-object-set.js
vendored
Normal file
11
spec/fixtures/module/remote-object-set.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
const {BrowserWindow} = require('electron')
|
||||
|
||||
class Foo {
|
||||
set bar (value) {
|
||||
if (!(value instanceof BrowserWindow)) {
|
||||
throw new Error('setting error')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Foo()
|
||||
@@ -91,6 +91,16 @@ describe('node feature', function () {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('works when sending a message to a process forked with the --eval argument', function (done) {
|
||||
const source = "process.on('message', (message) => { process.send(message) })"
|
||||
const forked = ChildProcess.fork('--eval', [source])
|
||||
forked.once('message', (message) => {
|
||||
assert.equal(message, 'hello')
|
||||
done()
|
||||
})
|
||||
forked.send('hello')
|
||||
})
|
||||
})
|
||||
|
||||
describe('child_process.spawn', function () {
|
||||
|
||||
Reference in New Issue
Block a user