electron/spec/static/main.js
Charles Kerr c83f836faf
refactor: prefer using app.whenReady() (#21972)
* docs: add references to app.whenReady() in isReady

* refactor: prefer app.whenReady()

In the docs, specs, and lib, replace instances of `app.once('ready')`
(seen occasionally) and `app.on('ready')` (extremely common) with
`app.whenReady()`.

It's better to encourage users to use whenReady():
1. it handles the edge case of registering for 'ready' after it's fired
2. it avoids the minor wart of leaving an active listener alive for
an event that wll never fire again
2020-02-03 22:43:22 +00:00

187 lines
5.5 KiB
JavaScript

// Deprecated APIs are still supported and should be tested.
process.throwDeprecation = false
const electron = require('electron')
const { app, BrowserWindow, crashReporter, dialog, ipcMain, protocol, webContents, session } = electron
try {
require('fs').rmdirSync(app.getPath('userData'), { recursive: true })
} catch (e) {
console.warn(`Warning: couldn't clear user data directory:`, e)
}
const fs = require('fs')
const path = require('path')
const util = require('util')
const v8 = require('v8')
const argv = require('yargs')
.boolean('ci')
.array('files')
.string('g').alias('g', 'grep')
.boolean('i').alias('i', 'invert')
.argv
let window = null
v8.setFlagsFromString('--expose_gc')
app.commandLine.appendSwitch('js-flags', '--expose_gc')
app.commandLine.appendSwitch('ignore-certificate-errors')
app.commandLine.appendSwitch('disable-renderer-backgrounding')
// Disable security warnings (the security warnings test will enable them)
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true
// Accessing stdout in the main process will result in the process.stdout
// throwing UnknownSystemError in renderer process sometimes. This line makes
// sure we can reproduce it in renderer process.
// eslint-disable-next-line
process.stdout
// Access console to reproduce #3482.
// eslint-disable-next-line
console
ipcMain.on('message', function (event, ...args) {
event.sender.send('message', ...args)
})
ipcMain.handle('get-modules', () => Object.keys(electron))
ipcMain.handle('get-temp-dir', () => app.getPath('temp'))
ipcMain.handle('ping', () => null)
// Write output to file if OUTPUT_TO_FILE is defined.
const outputToFile = process.env.OUTPUT_TO_FILE
const print = function (_, method, args) {
const output = util.format.apply(null, args)
if (outputToFile) {
fs.appendFileSync(outputToFile, output + '\n')
} else {
console[method](output)
}
}
ipcMain.on('console-call', print)
ipcMain.on('process.exit', function (event, code) {
process.exit(code)
})
ipcMain.on('eval', function (event, script) {
event.returnValue = eval(script) // eslint-disable-line
})
ipcMain.on('echo', function (event, msg) {
event.returnValue = msg
})
process.removeAllListeners('uncaughtException')
process.on('uncaughtException', function (error) {
console.error(error, error.stack)
process.exit(1)
})
global.nativeModulesEnabled = !process.env.ELECTRON_SKIP_NATIVE_MODULE_TESTS
app.on('window-all-closed', function () {
app.quit()
})
app.on('gpu-process-crashed', (event, killed) => {
console.log(`GPU process crashed (killed=${killed})`)
})
app.on('renderer-process-crashed', (event, contents, killed) => {
console.log(`webContents ${contents.id} crashed: ${contents.getURL()} (killed=${killed})`)
})
app.whenReady().then(async function () {
await session.defaultSession.clearCache()
await session.defaultSession.clearStorageData()
// Test if using protocol module would crash.
electron.protocol.registerStringProtocol('test-if-crashes', function () {})
window = new BrowserWindow({
title: 'Electron Tests',
show: false,
width: 800,
height: 600,
webPreferences: {
backgroundThrottling: false,
nodeIntegration: true,
enableRemoteModule: false,
webviewTag: true
}
})
window.loadFile('static/index.html', {
query: {
grep: argv.grep,
invert: argv.invert ? 'true' : '',
files: argv.files ? argv.files.join(',') : undefined
}
})
window.on('unresponsive', function () {
const chosen = dialog.showMessageBox(window, {
type: 'warning',
buttons: ['Close', 'Keep Waiting'],
message: 'Window is not responsing',
detail: 'The window is not responding. Would you like to force close it or just keep waiting?'
})
if (chosen === 0) window.destroy()
})
window.webContents.on('crashed', function () {
console.error('Renderer process crashed')
process.exit(1)
})
})
ipcMain.on('prevent-next-will-attach-webview', (event) => {
event.sender.once('will-attach-webview', event => event.preventDefault())
})
ipcMain.on('disable-node-on-next-will-attach-webview', (event, id) => {
event.sender.once('will-attach-webview', (event, webPreferences, params) => {
params.src = `file://${path.join(__dirname, '..', 'fixtures', 'pages', 'c.html')}`
webPreferences.nodeIntegration = false
})
})
ipcMain.on('disable-preload-on-next-will-attach-webview', (event, id) => {
event.sender.once('will-attach-webview', (event, webPreferences, params) => {
params.src = `file://${path.join(__dirname, '..', 'fixtures', 'pages', 'webview-stripped-preload.html')}`
delete webPreferences.preload
delete webPreferences.preloadURL
})
})
ipcMain.on('handle-uncaught-exception', (event, message) => {
suspendListeners(process, 'uncaughtException', (error) => {
event.returnValue = error.message
})
fs.readFile(__filename, () => {
throw new Error(message)
})
})
ipcMain.on('handle-unhandled-rejection', (event, message) => {
suspendListeners(process, 'unhandledRejection', (error) => {
event.returnValue = error.message
})
fs.readFile(__filename, () => {
Promise.reject(new Error(message))
})
})
// Suspend listeners until the next event and then restore them
const suspendListeners = (emitter, eventName, callback) => {
const listeners = emitter.listeners(eventName)
emitter.removeAllListeners(eventName)
emitter.once(eventName, (...args) => {
emitter.removeAllListeners(eventName)
listeners.forEach((listener) => {
emitter.on(eventName, listener)
})
// eslint-disable-next-line standard/no-callback-literal
callback(...args)
})
}