test: convert functions to async & eliminate duplicates (#37316)

test: convert functions to async

Co-authored-by: Milan Burda <miburda@microsoft.com>
This commit is contained in:
Milan Burda 2023-02-20 12:30:57 +01:00 committed by GitHub
parent 969665eaa2
commit f97d68c4bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 225 additions and 343 deletions

View file

@ -9,7 +9,7 @@ import { promisify } from 'util';
import { app, BrowserWindow, Menu, session, net as electronNet } from 'electron/main'; import { app, BrowserWindow, Menu, session, net as electronNet } from 'electron/main';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { closeWindow, closeAllWindows } from './lib/window-helpers'; import { closeWindow, closeAllWindows } from './lib/window-helpers';
import { ifdescribe, ifit, waitUntil } from './lib/spec-helpers'; import { ifdescribe, ifit, listen, waitUntil } from './lib/spec-helpers';
import split = require('split') import split = require('split')
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@ -33,7 +33,7 @@ describe('app module', () => {
let secureUrl: string; let secureUrl: string;
const certPath = path.join(fixturesPath, 'certificates'); const certPath = path.join(fixturesPath, 'certificates');
before((done) => { before(async () => {
const options = { const options = {
key: fs.readFileSync(path.join(certPath, 'server.key')), key: fs.readFileSync(path.join(certPath, 'server.key')),
cert: fs.readFileSync(path.join(certPath, 'server.pem')), cert: fs.readFileSync(path.join(certPath, 'server.pem')),
@ -55,11 +55,7 @@ describe('app module', () => {
} }
}); });
server.listen(0, '127.0.0.1', () => { secureUrl = (await listen(server)).url;
const port = (server.address() as net.AddressInfo).port;
secureUrl = `https://127.0.0.1:${port}`;
done();
});
}); });
after(done => { after(done => {
@ -1937,7 +1933,7 @@ describe('default behavior', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string; let serverUrl: string;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
if (request.headers.authorization) { if (request.headers.authorization) {
return response.end('ok'); return response.end('ok');
@ -1945,10 +1941,9 @@ describe('default behavior', () => {
response response
.writeHead(401, { 'WWW-Authenticate': 'Basic realm="Foo"' }) .writeHead(401, { 'WWW-Authenticate': 'Basic realm="Foo"' })
.end(); .end();
}).listen(0, '127.0.0.1', () => {
serverUrl = 'http://127.0.0.1:' + (server.address() as net.AddressInfo).port;
done();
}); });
serverUrl = (await listen(server)).url;
}); });
it('should emit a login event on app when a WebContents hits a 401', async () => { it('should emit a login event on app when a WebContents hits a 401', async () => {

View file

@ -5,11 +5,10 @@ import * as fs from 'fs';
import * as qs from 'querystring'; import * as qs from 'querystring';
import * as http from 'http'; import * as http from 'http';
import * as os from 'os'; import * as os from 'os';
import { AddressInfo } from 'net';
import { app, BrowserWindow, BrowserView, dialog, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents } from 'electron/main'; import { app, BrowserWindow, BrowserView, dialog, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents } from 'electron/main';
import { emittedOnce, emittedUntil, emittedNTimes } from './lib/events-helpers'; import { emittedOnce, emittedUntil, emittedNTimes } from './lib/events-helpers';
import { ifit, ifdescribe, defer, delay } from './lib/spec-helpers'; import { ifit, ifdescribe, defer, delay, listen } from './lib/spec-helpers';
import { closeWindow, closeAllWindows } from './lib/window-helpers'; import { closeWindow, closeAllWindows } from './lib/window-helpers';
import { areColorsSimilar, captureScreen, HexColors, getPixelColor } from './lib/screen-helpers'; import { areColorsSimilar, captureScreen, HexColors, getPixelColor } from './lib/screen-helpers';
@ -153,7 +152,7 @@ describe('BrowserWindow module', () => {
let server: http.Server; let server: http.Server;
let url: string; let url: string;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
switch (request.url) { switch (request.url) {
case '/net-error': case '/net-error':
@ -175,10 +174,9 @@ describe('BrowserWindow module', () => {
default: default:
throw new Error(`unsupported endpoint: ${request.url}`); throw new Error(`unsupported endpoint: ${request.url}`);
} }
}).listen(0, '127.0.0.1', () => {
url = 'http://127.0.0.1:' + (server.address() as AddressInfo).port;
done();
}); });
url = (await listen(server)).url;
}); });
after(() => { after(() => {
@ -297,7 +295,7 @@ describe('BrowserWindow module', () => {
let server: http.Server; let server: http.Server;
let url: string; let url: string;
let postData = null as any; let postData = null as any;
before((done) => { before(async () => {
const filePath = path.join(fixtures, 'pages', 'a.html'); const filePath = path.join(fixtures, 'pages', 'a.html');
const fileStats = fs.statSync(filePath); const fileStats = fs.statSync(filePath);
postData = [ postData = [
@ -340,10 +338,8 @@ describe('BrowserWindow module', () => {
} }
setTimeout(respond, req.url && req.url.includes('slow') ? 200 : 0); setTimeout(respond, req.url && req.url.includes('slow') ? 200 : 0);
}); });
server.listen(0, '127.0.0.1', () => {
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`; url = (await listen(server)).url;
done();
});
}); });
after(() => { after(() => {
@ -486,7 +482,7 @@ describe('BrowserWindow module', () => {
describe('will-navigate event', () => { describe('will-navigate event', () => {
let server: http.Server; let server: http.Server;
let url: string; let url: string;
before((done) => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
if (req.url === '/navigate-top') { if (req.url === '/navigate-top') {
res.end('<a target=_top href="/">navigate _top</a>'); res.end('<a target=_top href="/">navigate _top</a>');
@ -494,22 +490,18 @@ describe('BrowserWindow module', () => {
res.end(''); res.end('');
} }
}); });
server.listen(0, '127.0.0.1', () => { url = (await listen(server)).url;
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}/`;
done();
});
}); });
after(() => { after(() => {
server.close(); server.close();
}); });
it('allows the window to be closed from the event listener', (done) => { it('allows the window to be closed from the event listener', async () => {
w.webContents.once('will-navigate', () => { const event = emittedOnce(w.webContents, 'will-navigate');
w.close();
done();
});
w.loadFile(path.join(fixtures, 'pages', 'will-navigate.html')); w.loadFile(path.join(fixtures, 'pages', 'will-navigate.html'));
await event;
w.close();
}); });
it('can be prevented', (done) => { it('can be prevented', (done) => {
@ -541,7 +533,7 @@ describe('BrowserWindow module', () => {
resolve(url); resolve(url);
}); });
}); });
expect(navigatedTo).to.equal(url); expect(navigatedTo).to.equal(url + '/');
expect(w.webContents.getURL()).to.match(/^file:/); expect(w.webContents.getURL()).to.match(/^file:/);
}); });
@ -554,12 +546,12 @@ describe('BrowserWindow module', () => {
resolve(url); resolve(url);
}); });
}); });
expect(navigatedTo).to.equal(url); expect(navigatedTo).to.equal(url + '/');
expect(w.webContents.getURL()).to.equal('about:blank'); expect(w.webContents.getURL()).to.equal('about:blank');
}); });
it('is triggered when a cross-origin iframe navigates _top', async () => { it('is triggered when a cross-origin iframe navigates _top', async () => {
await w.loadURL(`data:text/html,<iframe src="http://127.0.0.1:${(server.address() as AddressInfo).port}/navigate-top"></iframe>`); await w.loadURL(`data:text/html,<iframe src="${url}/navigate-top"></iframe>`);
await delay(1000); await delay(1000);
w.webContents.debugger.attach('1.1'); w.webContents.debugger.attach('1.1');
const targets = await w.webContents.debugger.sendCommand('Target.getTargets'); const targets = await w.webContents.debugger.sendCommand('Target.getTargets');
@ -594,7 +586,7 @@ describe('BrowserWindow module', () => {
describe('will-redirect event', () => { describe('will-redirect event', () => {
let server: http.Server; let server: http.Server;
let url: string; let url: string;
before((done) => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
if (req.url === '/302') { if (req.url === '/302') {
res.setHeader('Location', '/200'); res.setHeader('Location', '/200');
@ -606,10 +598,7 @@ describe('BrowserWindow module', () => {
res.end(); res.end();
} }
}); });
server.listen(0, '127.0.0.1', () => { url = (await listen(server)).url;
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
done();
});
}); });
after(() => { after(() => {
@ -643,12 +632,11 @@ describe('BrowserWindow module', () => {
expect(stopCalled).to.equal(false, 'should not have called did-stop-loading first'); expect(stopCalled).to.equal(false, 'should not have called did-stop-loading first');
}); });
it('allows the window to be closed from the event listener', (done) => { it('allows the window to be closed from the event listener', async () => {
w.webContents.once('will-redirect', () => { const event = emittedOnce(w.webContents, 'will-redirect');
w.close();
done();
});
w.loadURL(`${url}/302`); w.loadURL(`${url}/302`);
await event;
w.close();
}); });
it('can be prevented', (done) => { it('can be prevented', (done) => {
@ -1914,9 +1902,7 @@ describe('BrowserWindow module', () => {
res.end(); res.end();
}); });
server.on('connection', () => { connections++; }); server.on('connection', () => { connections++; });
url = (await listen(server)).url;
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', () => resolve()));
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
}); });
afterEach(async () => { afterEach(async () => {
server.close(); server.close();
@ -2944,7 +2930,7 @@ describe('BrowserWindow module', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string; let serverUrl: string;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
switch (request.url) { switch (request.url) {
case '/cross-site': case '/cross-site':
@ -2953,10 +2939,8 @@ describe('BrowserWindow module', () => {
default: default:
throw new Error(`unsupported endpoint: ${request.url}`); throw new Error(`unsupported endpoint: ${request.url}`);
} }
}).listen(0, '127.0.0.1', () => {
serverUrl = 'http://127.0.0.1:' + (server.address() as AddressInfo).port;
done();
}); });
serverUrl = (await listen(server)).url;
}); });
after(() => { after(() => {
@ -4475,13 +4459,11 @@ describe('BrowserWindow module', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string; let serverUrl: string;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
response.end(); response.end();
}).listen(0, '127.0.0.1', () => {
serverUrl = 'http://127.0.0.1:' + (server.address() as AddressInfo).port;
done();
}); });
serverUrl = (await listen(server)).url;
}); });
after(() => { after(() => {

View file

@ -9,7 +9,7 @@ import * as cp from 'child_process';
import { closeWindow } from './lib/window-helpers'; import { closeWindow } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { AddressInfo } from 'net'; import { listen } from './lib/spec-helpers';
const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'context-bridge'); const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'context-bridge');
@ -17,13 +17,14 @@ describe('contextBridge', () => {
let w: BrowserWindow; let w: BrowserWindow;
let dir: string; let dir: string;
let server: http.Server; let server: http.Server;
let serverUrl: string;
before(async () => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
}); });
after(async () => { after(async () => {
@ -95,7 +96,7 @@ describe('contextBridge', () => {
additionalArguments: ['--unsafely-expose-electron-internals-for-testing'] additionalArguments: ['--unsafely-expose-electron-internals-for-testing']
} }
}); });
await w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`); await w.loadURL(serverUrl);
}; };
const callWithBindings = (fn: Function, worldId: number = 0) => const callWithBindings = (fn: Function, worldId: number = 0) =>

View file

@ -3,10 +3,9 @@ import * as childProcess from 'child_process';
import * as http from 'http'; import * as http from 'http';
import * as Busboy from 'busboy'; import * as Busboy from 'busboy';
import * as path from 'path'; import * as path from 'path';
import { ifdescribe, ifit, defer, startRemoteControlApp, delay, repeatedly } from './lib/spec-helpers'; import { ifdescribe, ifit, defer, startRemoteControlApp, delay, repeatedly, listen } from './lib/spec-helpers';
import { app } from 'electron/main'; import { app } from 'electron/main';
import { crashReporter } from 'electron/common'; import { crashReporter } from 'electron/common';
import { AddressInfo } from 'net';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import * as fs from 'fs'; import * as fs from 'fs';
import * as uuid from 'uuid'; import * as uuid from 'uuid';
@ -89,11 +88,7 @@ const startServer = async () => {
req.pipe(busboy); req.pipe(busboy);
}); });
await new Promise<void>(resolve => { const { port } = await listen(server);
server.listen(0, '127.0.0.1', () => { resolve(); });
});
const port = (server.address() as AddressInfo).port;
defer(() => { server.close(); }); defer(() => { server.close(); });

View file

@ -1,10 +1,10 @@
import { expect } from 'chai'; import { expect } from 'chai';
import * as http from 'http'; import * as http from 'http';
import * as path from 'path'; import * as path from 'path';
import { AddressInfo } from 'net';
import { BrowserWindow } from 'electron/main'; import { BrowserWindow } from 'electron/main';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce, emittedUntil } from './lib/events-helpers'; import { emittedOnce, emittedUntil } from './lib/events-helpers';
import { listen } from './lib/spec-helpers';
describe('debugger module', () => { describe('debugger module', () => {
const fixtures = path.resolve(__dirname, 'fixtures'); const fixtures = path.resolve(__dirname, 'fixtures');
@ -138,9 +138,9 @@ describe('debugger module', () => {
res.setHeader('Content-Type', 'text/plain; charset=utf-8'); res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('\u0024'); res.end('\u0024');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve));
w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`); const { url } = await listen(server);
w.loadURL(url);
// If we do this synchronously, it's fast enough to attach and enable // If we do this synchronously, it's fast enough to attach and enable
// network capture before the load. If we do it before the loadURL, for // network capture before the load. If we do it before the loadURL, for
// some reason network capture doesn't get enabled soon enough and we get // some reason network capture doesn't get enabled soon enough and we get
@ -155,30 +155,29 @@ describe('debugger module', () => {
expect(body).to.equal('\u0024'); expect(body).to.equal('\u0024');
}); });
it('does not crash for invalid unicode characters in message', (done) => { it('does not crash for invalid unicode characters in message', async () => {
try {
w.webContents.debugger.attach(); w.webContents.debugger.attach();
} catch (err) {
done(`unexpected error : ${err}`);
}
const loadingFinished = new Promise<void>(resolve => {
w.webContents.debugger.on('message', (event, method) => { w.webContents.debugger.on('message', (event, method) => {
// loadingFinished indicates that page has been loaded and it did not // loadingFinished indicates that page has been loaded and it did not
// crash because of invalid UTF-8 data // crash because of invalid UTF-8 data
if (method === 'Network.loadingFinished') { if (method === 'Network.loadingFinished') {
done(); resolve();
} }
}); });
});
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/plain; charset=utf-8'); res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('\uFFFF'); res.end('\uFFFF');
}); });
server.listen(0, '127.0.0.1', () => { const { url } = await listen(server);
w.webContents.debugger.sendCommand('Network.enable'); w.webContents.debugger.sendCommand('Network.enable');
w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`); w.loadURL(url);
});
await loadingFinished;
}); });
it('uses empty sessionId by default', async () => { it('uses empty sessionId by default', async () => {

View file

@ -3,10 +3,9 @@ import { expect } from 'chai';
import { BrowserWindow, ipcMain, IpcMainInvokeEvent, MessageChannelMain, WebContents } from 'electron/main'; import { BrowserWindow, ipcMain, IpcMainInvokeEvent, MessageChannelMain, WebContents } from 'electron/main';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { defer } from './lib/spec-helpers'; import { defer, listen } from './lib/spec-helpers';
import * as path from 'path'; import * as path from 'path';
import * as http from 'http'; import * as http from 'http';
import { AddressInfo } from 'net';
const v8Util = process._linkedBinding('electron_common_v8_util'); const v8Util = process._linkedBinding('electron_common_v8_util');
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@ -644,8 +643,7 @@ describe('ipc module', () => {
res.setHeader('content-type', 'text/html'); res.setHeader('content-type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
defer(() => { defer(() => {
server.close(); server.close();
}); });
@ -745,8 +743,7 @@ describe('ipc module', () => {
res.setHeader('content-type', 'text/html'); res.setHeader('content-type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
defer(() => { defer(() => {
server.close(); server.close();
}); });

View file

@ -2,7 +2,7 @@ import { expect } from 'chai';
import { BrowserWindow, session, desktopCapturer } from 'electron/main'; import { BrowserWindow, session, desktopCapturer } from 'electron/main';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import * as http from 'http'; import * as http from 'http';
import { ifdescribe, ifit } from './lib/spec-helpers'; import { ifdescribe, ifit, listen } from './lib/spec-helpers';
const features = process._linkedBinding('electron_common_features'); const features = process._linkedBinding('electron_common_features');
@ -17,8 +17,7 @@ ifdescribe(features.isDesktopCapturerEnabled())('setDisplayMediaRequestHandler',
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
after(() => { after(() => {
server.close(); server.close();

View file

@ -5,8 +5,8 @@ import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as ChildProcess from 'child_process'; import * as ChildProcess from 'child_process';
import { session, net } from 'electron/main'; import { session, net } from 'electron/main';
import { Socket, AddressInfo } from 'net'; import { Socket } from 'net';
import { ifit } from './lib/spec-helpers'; import { ifit, listen } from './lib/spec-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log'); const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log');
@ -20,12 +20,8 @@ describe('netLog module', () => {
let serverUrl: string; let serverUrl: string;
const connections: Set<Socket> = new Set(); const connections: Set<Socket> = new Set();
before(done => { before(async () => {
server = http.createServer(); server = http.createServer();
server.listen(0, '127.0.0.1', () => {
serverUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
done();
});
server.on('connection', (connection) => { server.on('connection', (connection) => {
connections.add(connection); connections.add(connection);
connection.once('close', () => { connection.once('close', () => {
@ -35,6 +31,7 @@ describe('netLog module', () => {
server.on('request', (request, response) => { server.on('request', (request, response) => {
response.end(); response.end();
}); });
serverUrl = (await listen(server)).url;
}); });
after(done => { after(done => {

View file

@ -3,9 +3,9 @@ import * as dns from 'dns';
import { net, session, ClientRequest, BrowserWindow, ClientRequestConstructorOptions } from 'electron/main'; import { net, session, ClientRequest, BrowserWindow, ClientRequestConstructorOptions } from 'electron/main';
import * as http from 'http'; import * as http from 'http';
import * as url from 'url'; import * as url from 'url';
import { AddressInfo, Socket } from 'net'; import { Socket } from 'net';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { defer, delay } from './lib/spec-helpers'; import { defer, delay, listen } from './lib/spec-helpers';
// See https://github.com/nodejs/node/issues/40702. // See https://github.com/nodejs/node/issues/40702.
dns.setDefaultResultOrder('ipv4first'); dns.setDefaultResultOrder('ipv4first');
@ -53,8 +53,7 @@ function collectStreamBodyBuffer (response: Electron.IncomingMessage | http.Inco
}); });
} }
function respondNTimes (fn: http.RequestListener, n: number): Promise<string> { async function respondNTimes (fn: http.RequestListener, n: number): Promise<string> {
return new Promise((resolve) => {
const server = http.createServer((request, response) => { const server = http.createServer((request, response) => {
fn(request, response); fn(request, response);
// don't close if a redirect was returned // don't close if a redirect was returned
@ -63,16 +62,13 @@ function respondNTimes (fn: http.RequestListener, n: number): Promise<string> {
server.close(); server.close();
} }
}); });
server.listen(0, '127.0.0.1', () => {
resolve(`http://127.0.0.1:${(server.address() as AddressInfo).port}`);
});
const sockets: Socket[] = []; const sockets: Socket[] = [];
server.on('connection', s => sockets.push(s)); server.on('connection', s => sockets.push(s));
defer(() => { defer(() => {
server.close(); server.close();
sockets.forEach(s => s.destroy()); sockets.forEach(s => s.destroy());
}); });
}); return (await listen(server)).url;
} }
function respondOnce (fn: http.RequestListener) { function respondOnce (fn: http.RequestListener) {

View file

@ -1,7 +1,6 @@
import { expect } from 'chai'; import { expect } from 'chai';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { protocol, webContents, WebContents, session, BrowserWindow, ipcMain } from 'electron/main'; import { protocol, webContents, WebContents, session, BrowserWindow, ipcMain } from 'electron/main';
import { AddressInfo } from 'net';
import * as ChildProcess from 'child_process'; import * as ChildProcess from 'child_process';
import * as path from 'path'; import * as path from 'path';
import * as http from 'http'; import * as http from 'http';
@ -12,7 +11,7 @@ import { EventEmitter } from 'events';
import { closeAllWindows, closeWindow } from './lib/window-helpers'; import { closeAllWindows, closeWindow } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { WebmGenerator } from './lib/video-helpers'; import { WebmGenerator } from './lib/video-helpers';
import { delay } from './lib/spec-helpers'; import { delay, listen } from './lib/spec-helpers';
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@ -324,10 +323,8 @@ describe('protocol module', () => {
res.end(text); res.end(text);
server.close(); server.close();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
const port = (server.address() as AddressInfo).port;
const url = 'http://127.0.0.1:' + port;
registerHttpProtocol(protocolName, (request, callback) => callback({ url })); registerHttpProtocol(protocolName, (request, callback) => callback({ url }));
const r = await ajax(protocolName + '://fake-host'); const r = await ajax(protocolName + '://fake-host');
expect(r.data).to.equal(text); expect(r.data).to.equal(text);
@ -354,9 +351,7 @@ describe('protocol module', () => {
} }
}); });
after(() => server.close()); after(() => server.close());
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
const url = `${protocolName}://fake-host`; const url = `${protocolName}://fake-host`;
const redirectURL = `http://127.0.0.1:${port}/serverRedirect`; const redirectURL = `http://127.0.0.1:${port}/serverRedirect`;
registerHttpProtocol(protocolName, (request, callback) => callback({ url: redirectURL })); registerHttpProtocol(protocolName, (request, callback) => callback({ url: redirectURL }));
@ -653,10 +648,7 @@ describe('protocol module', () => {
server.close(); server.close();
}); });
after(() => server.close()); after(() => server.close());
server.listen(0, '127.0.0.1'); const { url } = await listen(server);
const port = (server.address() as AddressInfo).port;
const url = `http://127.0.0.1:${port}`;
interceptHttpProtocol('http', (request, callback) => { interceptHttpProtocol('http', (request, callback) => {
const data: Electron.ProtocolResponse = { const data: Electron.ProtocolResponse = {
url: url, url: url,
@ -874,9 +866,8 @@ describe('protocol module', () => {
server.close(); server.close();
requestReceived.resolve(); requestReceived.resolve();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
const port = (server.address() as AddressInfo).port; const content = `<script>fetch(${JSON.stringify(url)})</script>`;
const content = `<script>fetch("http://127.0.0.1:${port}")</script>`;
registerStringProtocol(standardScheme, (request, callback) => callback({ data: content, mimeType: 'text/html' })); registerStringProtocol(standardScheme, (request, callback) => callback({ data: content, mimeType: 'text/html' }));
await w.loadURL(origin); await w.loadURL(origin);
await requestReceived; await requestReceived;

View file

@ -4,8 +4,8 @@ import * as path from 'path';
import { session, webContents, WebContents } from 'electron/main'; import { session, webContents, WebContents } from 'electron/main';
import { expect } from 'chai'; import { expect } from 'chai';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { AddressInfo } from 'net';
import { emittedOnce, emittedNTimes } from './lib/events-helpers'; import { emittedOnce, emittedNTimes } from './lib/events-helpers';
import { listen } from './lib/spec-helpers';
const partition = 'service-workers-spec'; const partition = 'service-workers-spec';
@ -32,12 +32,8 @@ describe('session.serviceWorkers', () => {
} }
res.end(fs.readFileSync(path.resolve(__dirname, 'fixtures', 'api', 'service-workers', file))); res.end(fs.readFileSync(path.resolve(__dirname, 'fixtures', 'api', 'service-workers', file)));
}); });
await new Promise<void>(resolve => { const { port } = await listen(server);
server.listen(0, '127.0.0.1', () => { baseUrl = `http://localhost:${port}/${uuid}`;
baseUrl = `http://localhost:${(server.address() as AddressInfo).port}/${uuid}`;
resolve();
});
});
w = (webContents as typeof ElectronInternal.WebContents).create({ session: ses }); w = (webContents as typeof ElectronInternal.WebContents).create({ session: ses });
}); });

View file

@ -9,8 +9,7 @@ import * as send from 'send';
import * as auth from 'basic-auth'; import * as auth from 'basic-auth';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { defer, delay } from './lib/spec-helpers'; import { defer, delay, listen } from './lib/spec-helpers';
import { AddressInfo } from 'net';
/* The whole session API doesn't use standard callbacks */ /* The whole session API doesn't use standard callbacks */
/* eslint-disable standard/no-callback-literal */ /* eslint-disable standard/no-callback-literal */
@ -51,8 +50,7 @@ describe('session module', () => {
res.end('finished'); res.end('finished');
server.close(); server.close();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const { port } = server.address() as AddressInfo;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
await w.loadURL(`${url}:${port}`); await w.loadURL(`${url}:${port}`);
const list = await w.webContents.session.cookies.get({ url }); const list = await w.webContents.session.cookies.get({ url });
@ -275,10 +273,7 @@ describe('session module', () => {
res.end(mockFile); res.end(mockFile);
downloadServer.close(); downloadServer.close();
}); });
await new Promise<void>(resolve => downloadServer.listen(0, '127.0.0.1', resolve)); const url = (await listen(downloadServer)).url;
const port = (downloadServer.address() as AddressInfo).port;
const url = `http://127.0.0.1:${port}/`;
const downloadPrevented: Promise<{itemUrl: string, itemFilename: string, item: Electron.DownloadItem}> = new Promise(resolve => { const downloadPrevented: Promise<{itemUrl: string, itemFilename: string, item: Electron.DownloadItem}> = new Promise(resolve => {
w.webContents.session.once('will-download', function (e, item) { w.webContents.session.once('will-download', function (e, item) {
@ -288,7 +283,7 @@ describe('session module', () => {
}); });
w.loadURL(url); w.loadURL(url);
const { item, itemUrl, itemFilename } = await downloadPrevented; const { item, itemUrl, itemFilename } = await downloadPrevented;
expect(itemUrl).to.equal(url); expect(itemUrl).to.equal(url + '/');
expect(itemFilename).to.equal('mockFile.txt'); expect(itemFilename).to.equal('mockFile.txt');
// Delay till the next tick. // Delay till the next tick.
await new Promise(setImmediate); await new Promise(setImmediate);
@ -392,15 +387,15 @@ describe('session module', () => {
}); });
res.end(pac); res.end(pac);
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
{ {
const config = { pacScript: `http://127.0.0.1:${(server.address() as AddressInfo).port}` }; const config = { pacScript: url };
await customSession.setProxy(config); await customSession.setProxy(config);
const proxy = await customSession.resolveProxy('https://google.com'); const proxy = await customSession.resolveProxy('https://google.com');
expect(proxy).to.equal('PROXY myproxy:8132'); expect(proxy).to.equal('PROXY myproxy:8132');
} }
{ {
const config = { mode: 'pac_script' as any, pacScript: `http://127.0.0.1:${(server.address() as AddressInfo).port}` }; const config = { mode: 'pac_script' as any, pacScript: url };
await customSession.setProxy(config); await customSession.setProxy(config);
const proxy = await customSession.resolveProxy('https://google.com'); const proxy = await customSession.resolveProxy('https://google.com');
expect(proxy).to.equal('PROXY myproxy:8132'); expect(proxy).to.equal('PROXY myproxy:8132');
@ -466,8 +461,8 @@ describe('session module', () => {
}); });
res.end(pac); res.end(pac);
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
const config = { mode: 'pac_script' as any, pacScript: `http://127.0.0.1:${(server.address() as AddressInfo).port}` }; const config = { mode: 'pac_script' as any, pacScript: url };
await customSession.setProxy(config); await customSession.setProxy(config);
{ {
const proxy = await customSession.resolveProxy('https://google.com'); const proxy = await customSession.resolveProxy('https://google.com');
@ -575,8 +570,9 @@ describe('session module', () => {
describe('ses.setCertificateVerifyProc(callback)', () => { describe('ses.setCertificateVerifyProc(callback)', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string;
beforeEach((done) => { beforeEach(async () => {
const certPath = path.join(fixtures, 'certificates'); const certPath = path.join(fixtures, 'certificates');
const options = { const options = {
key: fs.readFileSync(path.join(certPath, 'server.key')), key: fs.readFileSync(path.join(certPath, 'server.key')),
@ -592,7 +588,7 @@ describe('session module', () => {
res.writeHead(200); res.writeHead(200);
res.end('<title>hello</title>'); res.end('<title>hello</title>');
}); });
server.listen(0, '127.0.0.1', done); serverUrl = (await listen(server)).url;
}); });
afterEach((done) => { afterEach((done) => {
@ -613,7 +609,7 @@ describe('session module', () => {
}); });
const w = new BrowserWindow({ show: false, webPreferences: { session: ses } }); const w = new BrowserWindow({ show: false, webPreferences: { session: ses } });
await w.loadURL(`https://127.0.0.1:${(server.address() as AddressInfo).port}`); await w.loadURL(serverUrl);
expect(w.webContents.getTitle()).to.equal('hello'); expect(w.webContents.getTitle()).to.equal('hello');
expect(validate!).not.to.be.undefined(); expect(validate!).not.to.be.undefined();
validate!(); validate!();
@ -640,10 +636,9 @@ describe('session module', () => {
callback(-2); callback(-2);
}); });
const url = `https://127.0.0.1:${(server.address() as AddressInfo).port}`;
const w = new BrowserWindow({ show: false, webPreferences: { session: ses } }); const w = new BrowserWindow({ show: false, webPreferences: { session: ses } });
await expect(w.loadURL(url)).to.eventually.be.rejectedWith(/ERR_FAILED/); await expect(w.loadURL(serverUrl)).to.eventually.be.rejectedWith(/ERR_FAILED/);
expect(w.webContents.getTitle()).to.equal(url); expect(w.webContents.getTitle()).to.equal(serverUrl);
expect(validate!).not.to.be.undefined(); expect(validate!).not.to.be.undefined();
validate!(); validate!();
}); });
@ -657,12 +652,11 @@ describe('session module', () => {
callback(-2); callback(-2);
}); });
const url = `https://127.0.0.1:${(server.address() as AddressInfo).port}`;
const w = new BrowserWindow({ show: false, webPreferences: { session: ses } }); const w = new BrowserWindow({ show: false, webPreferences: { session: ses } });
await expect(w.loadURL(url), 'first load').to.eventually.be.rejectedWith(/ERR_FAILED/); await expect(w.loadURL(serverUrl), 'first load').to.eventually.be.rejectedWith(/ERR_FAILED/);
await emittedOnce(w.webContents, 'did-stop-loading'); await emittedOnce(w.webContents, 'did-stop-loading');
await expect(w.loadURL(url + '/test'), 'second load').to.eventually.be.rejectedWith(/ERR_FAILED/); await expect(w.loadURL(serverUrl + '/test'), 'second load').to.eventually.be.rejectedWith(/ERR_FAILED/);
expect(w.webContents.getTitle()).to.equal(url + '/test'); expect(w.webContents.getTitle()).to.equal(serverUrl + '/test');
expect(numVerificationRequests).to.equal(1); expect(numVerificationRequests).to.equal(1);
}); });
@ -671,8 +665,7 @@ describe('session module', () => {
ses1.setCertificateVerifyProc((opts, cb) => cb(0)); ses1.setCertificateVerifyProc((opts, cb) => cb(0));
const ses2 = session.fromPartition(`${Math.random()}`); const ses2 = session.fromPartition(`${Math.random()}`);
const url = `https://127.0.0.1:${(server.address() as AddressInfo).port}`; const req = net.request({ url: serverUrl, session: ses1, credentials: 'include' });
const req = net.request({ url, session: ses1, credentials: 'include' });
req.end(); req.end();
setTimeout(() => { setTimeout(() => {
ses2.setCertificateVerifyProc((opts, callback) => callback(0)); ses2.setCertificateVerifyProc((opts, callback) => callback(0));
@ -701,8 +694,7 @@ describe('session module', () => {
res.end('authenticated'); res.end('authenticated');
} }
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
const fetch = (url: string) => new Promise((resolve, reject) => { const fetch = (url: string) => new Promise((resolve, reject) => {
const request = net.request({ url, session: ses }); const request = net.request({ url, session: ses });
request.on('response', (response) => { request.on('response', (response) => {
@ -742,7 +734,7 @@ describe('session module', () => {
const downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); const downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf');
const protocolName = 'custom-dl'; const protocolName = 'custom-dl';
const contentDisposition = 'inline; filename="mock.pdf"'; const contentDisposition = 'inline; filename="mock.pdf"';
let address: AddressInfo; let port: number;
let downloadServer: http.Server; let downloadServer: http.Server;
before(async () => { before(async () => {
downloadServer = http.createServer((req, res) => { downloadServer = http.createServer((req, res) => {
@ -753,8 +745,7 @@ describe('session module', () => {
}); });
res.end(mockPDF); res.end(mockPDF);
}); });
await new Promise<void>(resolve => downloadServer.listen(0, '127.0.0.1', resolve)); port = (await listen(downloadServer)).port;
address = downloadServer.address() as AddressInfo;
}); });
after(async () => { after(async () => {
await new Promise(resolve => downloadServer.close(resolve)); await new Promise(resolve => downloadServer.close(resolve));
@ -772,7 +763,7 @@ describe('session module', () => {
if (isCustom) { if (isCustom) {
expect(item.getURL()).to.equal(`${protocolName}://item`); expect(item.getURL()).to.equal(`${protocolName}://item`);
} else { } else {
expect(item.getURL()).to.be.equal(`${url}:${address.port}/`); expect(item.getURL()).to.be.equal(`${url}:${port}/`);
} }
expect(item.getMimeType()).to.equal('application/pdf'); expect(item.getMimeType()).to.equal('application/pdf');
expect(item.getReceivedBytes()).to.equal(mockPDF.length); expect(item.getReceivedBytes()).to.equal(mockPDF.length);
@ -783,7 +774,6 @@ describe('session module', () => {
}; };
it('can download using session.downloadURL', (done) => { it('can download using session.downloadURL', (done) => {
const port = address.port;
session.defaultSession.once('will-download', function (e, item) { session.defaultSession.once('will-download', function (e, item) {
item.savePath = downloadFilePath; item.savePath = downloadFilePath;
item.on('done', function (e, state) { item.on('done', function (e, state) {
@ -799,7 +789,6 @@ describe('session module', () => {
}); });
it('can download using WebContents.downloadURL', (done) => { it('can download using WebContents.downloadURL', (done) => {
const port = address.port;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.webContents.session.once('will-download', function (e, item) { w.webContents.session.once('will-download', function (e, item) {
item.savePath = downloadFilePath; item.savePath = downloadFilePath;
@ -817,7 +806,6 @@ describe('session module', () => {
it('can download from custom protocols using WebContents.downloadURL', (done) => { it('can download from custom protocols using WebContents.downloadURL', (done) => {
const protocol = session.defaultSession.protocol; const protocol = session.defaultSession.protocol;
const port = address.port;
const handler = (ignoredError: any, callback: Function) => { const handler = (ignoredError: any, callback: Function) => {
callback({ url: `${url}:${port}` }); callback({ url: `${url}:${port}` });
}; };
@ -838,7 +826,6 @@ describe('session module', () => {
}); });
it('can download using WebView.downloadURL', async () => { it('can download using WebView.downloadURL', async () => {
const port = address.port;
const w = new BrowserWindow({ show: false, webPreferences: { webviewTag: true } }); const w = new BrowserWindow({ show: false, webPreferences: { webviewTag: true } });
await w.loadURL('about:blank'); await w.loadURL('about:blank');
function webviewDownload ({ fixtures, url, port }: {fixtures: string, url: string, port: string}) { function webviewDownload ({ fixtures, url, port }: {fixtures: string, url: string, port: string}) {
@ -863,7 +850,6 @@ describe('session module', () => {
}); });
it('can cancel download', (done) => { it('can cancel download', (done) => {
const port = address.port;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.webContents.session.once('will-download', function (e, item) { w.webContents.session.once('will-download', function (e, item) {
item.savePath = downloadFilePath; item.savePath = downloadFilePath;
@ -892,7 +878,6 @@ describe('session module', () => {
return done(); return done();
} }
const port = address.port;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.webContents.session.once('will-download', function (e, item) { w.webContents.session.once('will-download', function (e, item) {
item.savePath = downloadFilePath; item.savePath = downloadFilePath;
@ -911,7 +896,6 @@ describe('session module', () => {
it('can set options for the save dialog', (done) => { it('can set options for the save dialog', (done) => {
const filePath = path.join(__dirname, 'fixtures', 'mock.pdf'); const filePath = path.join(__dirname, 'fixtures', 'mock.pdf');
const port = address.port;
const options = { const options = {
window: null, window: null,
title: 'title', title: 'title',
@ -999,8 +983,7 @@ describe('session module', () => {
.on('error', (error: any) => { throw error; }).pipe(res); .on('error', (error: any) => { throw error; }).pipe(res);
}); });
try { try {
await new Promise<void>(resolve => rangeServer.listen(0, '127.0.0.1', resolve)); const { url } = await listen(rangeServer);
const port = (rangeServer.address() as AddressInfo).port;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
const downloadCancelled: Promise<Electron.DownloadItem> = new Promise((resolve) => { const downloadCancelled: Promise<Electron.DownloadItem> = new Promise((resolve) => {
w.webContents.session.once('will-download', function (e, item) { w.webContents.session.once('will-download', function (e, item) {
@ -1011,7 +994,7 @@ describe('session module', () => {
item.cancel(); item.cancel();
}); });
}); });
const downloadUrl = `http://127.0.0.1:${port}/assets/logo.png`; const downloadUrl = `${url}/assets/logo.png`;
w.webContents.downloadURL(downloadUrl); w.webContents.downloadURL(downloadUrl);
const item = await downloadCancelled; const item = await downloadCancelled;
expect(item.getState()).to.equal('cancelled'); expect(item.getState()).to.equal('cancelled');
@ -1062,8 +1045,7 @@ describe('session module', () => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
after(() => { after(() => {
server.close(); server.close();
@ -1269,8 +1251,8 @@ describe('session module', () => {
res.end(); res.end();
server.close(); server.close();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
await w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`); await w.loadURL(url);
expect(headers!['user-agent']).to.equal(userAgent); expect(headers!['user-agent']).to.equal(userAgent);
expect(headers!['accept-language']).to.equal('en-US,fr;q=0.9,de;q=0.8'); expect(headers!['accept-language']).to.equal('en-US,fr;q=0.9,de;q=0.8');
}); });
@ -1335,9 +1317,8 @@ describe('session module', () => {
}, (req, res) => { }, (req, res) => {
res.end('hi'); res.end('hi');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
defer(() => server.close()); defer(() => server.close());
const { port } = server.address() as AddressInfo;
function request () { function request () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View file

@ -2,12 +2,11 @@ import { BrowserWindow, app } from 'electron/main';
import { shell } from 'electron/common'; import { shell } from 'electron/common';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { ifdescribe, ifit } from './lib/spec-helpers'; import { ifdescribe, ifit, listen } from './lib/spec-helpers';
import * as http from 'http'; import * as http from 'http';
import * as fs from 'fs-extra'; import * as fs from 'fs-extra';
import * as os from 'os'; import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import { AddressInfo } from 'net';
import { expect } from 'chai'; import { expect } from 'chai';
describe('shell module', () => { describe('shell module', () => {
@ -51,9 +50,8 @@ describe('shell module', () => {
const server = http.createServer((req, res) => { const server = http.createServer((req, res) => {
res.end(); res.end();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); url = (await listen(server)).url;
requestReceived = new Promise<void>(resolve => server.on('connection', () => resolve())); requestReceived = new Promise<void>(resolve => server.on('connection', () => resolve()));
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
} }
await Promise.all<void>([ await Promise.all<void>([

View file

@ -4,8 +4,7 @@ import * as http from 'http';
import { emittedNTimes, emittedOnce } from './lib/events-helpers'; import { emittedNTimes, emittedOnce } from './lib/events-helpers';
import { closeWindow } from './lib/window-helpers'; import { closeWindow } from './lib/window-helpers';
import { app, BrowserWindow, ipcMain } from 'electron/main'; import { app, BrowserWindow, ipcMain } from 'electron/main';
import { AddressInfo } from 'net'; import { ifdescribe, listen } from './lib/spec-helpers';
import { ifdescribe } from './lib/spec-helpers';
describe('renderer nodeIntegrationInSubFrames', () => { describe('renderer nodeIntegrationInSubFrames', () => {
const generateTests = (description: string, webPreferences: any) => { const generateTests = (description: string, webPreferences: any) => {
@ -218,15 +217,12 @@ ifdescribe(process.platform !== 'linux')('cross-site frame sandboxing', () => {
let crossSiteUrl: string; let crossSiteUrl: string;
let serverUrl: string; let serverUrl: string;
before(function (done) { before(async function () {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
res.end(`<iframe name="frame" src="${crossSiteUrl}" />`); res.end(`<iframe name="frame" src="${crossSiteUrl}" />`);
}); });
server.listen(0, '127.0.0.1', () => { serverUrl = (await listen(server)).url;
serverUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}/`; crossSiteUrl = serverUrl.replace('127.0.0.1', 'localhost');
crossSiteUrl = `http://localhost:${(server.address() as AddressInfo).port}/`;
done();
});
}); });
after(() => { after(() => {

View file

@ -6,7 +6,7 @@ import * as http from 'http';
import { BrowserWindow, ipcMain, webContents, session, app, BrowserView } from 'electron/main'; import { BrowserWindow, ipcMain, webContents, session, app, BrowserView } from 'electron/main';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { ifdescribe, delay, defer, waitUntil } from './lib/spec-helpers'; import { ifdescribe, delay, defer, waitUntil, listen } from './lib/spec-helpers';
const pdfjs = require('pdfjs-dist'); const pdfjs = require('pdfjs-dist');
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@ -295,13 +295,11 @@ describe('webContents module', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string; let serverUrl: string;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
response.end(); response.end();
}).listen(0, '127.0.0.1', () => {
serverUrl = 'http://127.0.0.1:' + (server.address() as AddressInfo).port;
done();
}); });
serverUrl = (await listen(server)).url;
}); });
after(() => { after(() => {
@ -430,8 +428,7 @@ describe('webContents module', () => {
it('rejects if the load is aborted', async () => { it('rejects if the load is aborted', async () => {
const s = http.createServer(() => { /* never complete the request */ }); const s = http.createServer(() => { /* never complete the request */ });
await new Promise<void>(resolve => s.listen(0, '127.0.0.1', resolve)); const { port } = await listen(s);
const { port } = s.address() as AddressInfo;
const p = expect(w.loadURL(`http://127.0.0.1:${port}`)).to.eventually.be.rejectedWith(Error, /ERR_ABORTED/); const p = expect(w.loadURL(`http://127.0.0.1:${port}`)).to.eventually.be.rejectedWith(Error, /ERR_ABORTED/);
// load a different file before the first load completes, causing the // load a different file before the first load completes, causing the
// first load to be aborted. // first load to be aborted.
@ -448,8 +445,7 @@ describe('webContents module', () => {
resp = res; resp = res;
// don't end the response yet // don't end the response yet
}); });
await new Promise<void>(resolve => s.listen(0, '127.0.0.1', resolve)); const { port } = await listen(s);
const { port } = s.address() as AddressInfo;
const p = new Promise<void>(resolve => { const p = new Promise<void>(resolve => {
w.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => { w.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => {
if (!isMainFrame) { if (!isMainFrame) {
@ -472,8 +468,7 @@ describe('webContents module', () => {
resp = res; resp = res;
// don't end the response yet // don't end the response yet
}); });
await new Promise<void>(resolve => s.listen(0, '127.0.0.1', resolve)); const { port } = await listen(s);
const { port } = s.address() as AddressInfo;
const p = new Promise<void>(resolve => { const p = new Promise<void>(resolve => {
w.webContents.on('did-frame-finish-load', (event, isMainFrame) => { w.webContents.on('did-frame-finish-load', (event, isMainFrame) => {
if (!isMainFrame) { if (!isMainFrame) {
@ -841,11 +836,12 @@ describe('webContents module', () => {
describe('inspectElement()', () => { describe('inspectElement()', () => {
afterEach(closeAllWindows); afterEach(closeAllWindows);
it('supports inspecting an element in the devtools', (done) => { it('supports inspecting an element in the devtools', async () => {
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.loadURL('about:blank'); w.loadURL('about:blank');
w.webContents.once('devtools-opened', () => { done(); }); const event = emittedOnce(w.webContents, 'devtools-opened');
w.webContents.inspectElement(10, 10); w.webContents.inspectElement(10, 10);
await event;
}); });
}); });
@ -1234,15 +1230,12 @@ describe('webContents module', () => {
let serverUrl: string; let serverUrl: string;
let crossSiteUrl: string; let crossSiteUrl: string;
before((done) => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
setTimeout(() => res.end('hey'), 0); setTimeout(() => res.end('hey'), 0);
}); });
server.listen(0, '127.0.0.1', () => { serverUrl = (await listen(server)).url;
serverUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`; crossSiteUrl = serverUrl.replace('127.0.0.1', 'localhost');
crossSiteUrl = `http://localhost:${(server.address() as AddressInfo).port}`;
done();
});
}); });
after(() => { after(() => {
@ -1340,7 +1333,7 @@ describe('webContents module', () => {
let serverUrl: string; let serverUrl: string;
let crossSiteUrl: string; let crossSiteUrl: string;
before((done) => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
const respond = () => { const respond = () => {
if (req.url === '/redirect-cross-site') { if (req.url === '/redirect-cross-site') {
@ -1359,11 +1352,8 @@ describe('webContents module', () => {
}; };
setTimeout(respond, 0); setTimeout(respond, 0);
}); });
server.listen(0, '127.0.0.1', () => { serverUrl = (await listen(server)).url;
serverUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`; crossSiteUrl = serverUrl.replace('127.0.0.1', 'localhost');
crossSiteUrl = `http://localhost:${(server.address() as AddressInfo).port}`;
done();
});
}); });
after(() => { after(() => {
@ -2110,7 +2100,7 @@ describe('webContents module', () => {
let proxyServer: http.Server; let proxyServer: http.Server;
let proxyServerPort: number; let proxyServerPort: number;
before((done) => { before(async () => {
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
if (request.url === '/no-auth') { if (request.url === '/no-auth') {
return response.end('ok'); return response.end('ok');
@ -2122,14 +2112,11 @@ describe('webContents module', () => {
response response
.writeHead(401, { 'WWW-Authenticate': 'Basic realm="Foo"' }) .writeHead(401, { 'WWW-Authenticate': 'Basic realm="Foo"' })
.end('401'); .end('401');
}).listen(0, '127.0.0.1', () => {
serverPort = (server.address() as AddressInfo).port;
serverUrl = `http://127.0.0.1:${serverPort}`;
done();
}); });
({ port: serverPort, url: serverUrl } = await listen(server));
}); });
before((done) => { before(async () => {
proxyServer = http.createServer((request, response) => { proxyServer = http.createServer((request, response) => {
if (request.headers['proxy-authorization']) { if (request.headers['proxy-authorization']) {
response.writeHead(200, { 'Content-type': 'text/plain' }); response.writeHead(200, { 'Content-type': 'text/plain' });
@ -2138,10 +2125,8 @@ describe('webContents module', () => {
response response
.writeHead(407, { 'Proxy-Authenticate': 'Basic realm="Foo"' }) .writeHead(407, { 'Proxy-Authenticate': 'Basic realm="Foo"' })
.end(); .end();
}).listen(0, '127.0.0.1', () => {
proxyServerPort = (proxyServer.address() as AddressInfo).port;
done();
}); });
proxyServerPort = (await listen(proxyServer)).port;
}); });
afterEach(async () => { afterEach(async () => {
@ -2225,13 +2210,13 @@ describe('webContents module', () => {
}); });
describe('crashed event', () => { describe('crashed event', () => {
it('does not crash main process when destroying WebContents in it', (done) => { it('does not crash main process when destroying WebContents in it', async () => {
const contents = (webContents as typeof ElectronInternal.WebContents).create({ nodeIntegration: true }); const contents = (webContents as typeof ElectronInternal.WebContents).create({ nodeIntegration: true });
contents.once('render-process-gone', () => { const crashEvent = emittedOnce(contents, 'render-process-gone');
await contents.loadURL('about:blank');
contents.forcefullyCrashRenderer();
await crashEvent;
contents.destroy(); contents.destroy();
done();
});
contents.loadURL('about:blank').then(() => contents.forcefullyCrashRenderer());
}); });
}); });

View file

@ -5,8 +5,7 @@ import * as url from 'url';
import { BrowserWindow, WebFrameMain, webFrameMain, ipcMain, app, WebContents } from 'electron/main'; import { BrowserWindow, WebFrameMain, webFrameMain, ipcMain, app, WebContents } from 'electron/main';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce, emittedNTimes } from './lib/events-helpers'; import { emittedOnce, emittedNTimes } from './lib/events-helpers';
import { AddressInfo } from 'net'; import { defer, delay, ifit, listen, waitUntil } from './lib/spec-helpers';
import { defer, delay, ifit, waitUntil } from './lib/spec-helpers';
describe('webFrameMain module', () => { describe('webFrameMain module', () => {
const fixtures = path.resolve(__dirname, 'fixtures'); const fixtures = path.resolve(__dirname, 'fixtures');
@ -17,7 +16,7 @@ describe('webFrameMain module', () => {
type Server = { server: http.Server, url: string } type Server = { server: http.Server, url: string }
/** Creates an HTTP server whose handler embeds the given iframe src. */ /** Creates an HTTP server whose handler embeds the given iframe src. */
const createServer = () => new Promise<Server>(resolve => { const createServer = async () => {
const server = http.createServer((req, res) => { const server = http.createServer((req, res) => {
const params = new URLSearchParams(url.parse(req.url || '').search || ''); const params = new URLSearchParams(url.parse(req.url || '').search || '');
if (params.has('frameSrc')) { if (params.has('frameSrc')) {
@ -26,11 +25,8 @@ describe('webFrameMain module', () => {
res.end(''); res.end('');
} }
}); });
server.listen(0, '127.0.0.1', () => { return { server, url: (await listen(server)).url + '/' };
const url = `http://127.0.0.1:${(server.address() as AddressInfo).port}/`; };
resolve({ server, url });
});
});
afterEach(closeAllWindows); afterEach(closeAllWindows);
@ -390,7 +386,7 @@ describe('webFrameMain module', () => {
// HACK: Use 'localhost' instead of '127.0.0.1' so Chromium treats it as // HACK: Use 'localhost' instead of '127.0.0.1' so Chromium treats it as
// a separate origin because differing ports aren't enough 🤔 // a separate origin because differing ports aren't enough 🤔
const secondUrl = `http://localhost:${new URL(server.url).port}`; const secondUrl = server.url.replace('127.0.0.1', 'localhost');
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
await w.webContents.loadURL(server.url); await w.webContents.loadURL(server.url);

View file

@ -5,8 +5,9 @@ import * as path from 'path';
import * as url from 'url'; import * as url from 'url';
import * as WebSocket from 'ws'; import * as WebSocket from 'ws';
import { ipcMain, protocol, session, WebContents, webContents } from 'electron/main'; import { ipcMain, protocol, session, WebContents, webContents } from 'electron/main';
import { AddressInfo, Socket } from 'net'; import { Socket } from 'net';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { listen } from './lib/spec-helpers';
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@ -35,13 +36,9 @@ describe('webRequest module', () => {
}); });
let defaultURL: string; let defaultURL: string;
before((done) => { before(async () => {
protocol.registerStringProtocol('cors', (req, cb) => cb('')); protocol.registerStringProtocol('cors', (req, cb) => cb(''));
server.listen(0, '127.0.0.1', () => { defaultURL = (await listen(server)).url + '/';
const port = (server.address() as AddressInfo).port;
defaultURL = `http://127.0.0.1:${port}/`;
done();
});
}); });
after(() => { after(() => {
@ -489,8 +486,7 @@ describe('webRequest module', () => {
}); });
// Start server. // Start server.
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = String((server.address() as AddressInfo).port);
// Use a separate session for testing. // Use a separate session for testing.
const ses = session.fromPartition('WebRequestWebSocket'); const ses = session.fromPartition('WebRequestWebSocket');
@ -548,7 +544,7 @@ describe('webRequest module', () => {
ses.webRequest.onCompleted(null); ses.webRequest.onCompleted(null);
}); });
contents.loadFile(path.join(fixturesPath, 'api', 'webrequest.html'), { query: { port } }); contents.loadFile(path.join(fixturesPath, 'api', 'webrequest.html'), { query: { port: `${port}` } });
await emittedOnce(ipcMain, 'websocket-success'); await emittedOnce(ipcMain, 'websocket-success');
expect(receivedHeaders['/websocket'].Upgrade[0]).to.equal('websocket'); expect(receivedHeaders['/websocket'].Upgrade[0]).to.equal('websocket');

View file

@ -10,8 +10,7 @@ import * as url from 'url';
import * as ChildProcess from 'child_process'; import * as ChildProcess from 'child_process';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { promisify } from 'util'; import { promisify } from 'util';
import { ifit, ifdescribe, defer, delay, itremote } from './lib/spec-helpers'; import { ifit, ifdescribe, defer, delay, itremote, listen } from './lib/spec-helpers';
import { AddressInfo } from 'net';
import { PipeTransport } from './pipe-transport'; import { PipeTransport } from './pipe-transport';
import * as ws from 'ws'; import * as ws from 'ws';
@ -60,18 +59,17 @@ describe('reporting api', () => {
// "deprecation" report. // "deprecation" report.
res.end('<script>webkitRequestAnimationFrame(() => {})</script>'); res.end('<script>webkitRequestAnimationFrame(() => {})</script>');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { url } = await listen(server);
const bw = new BrowserWindow({ const bw = new BrowserWindow({
show: false show: false
}); });
try { try {
const reportGenerated = emittedOnce(reports, 'report'); const reportGenerated = emittedOnce(reports, 'report');
const url = `https://localhost:${(server.address() as any).port}/a`;
await bw.loadURL(url); await bw.loadURL(url);
const [report] = await reportGenerated; const [report] = await reportGenerated;
expect(report).to.be.an('array'); expect(report).to.be.an('array');
expect(report[0].type).to.equal('deprecation'); expect(report[0].type).to.equal('deprecation');
expect(report[0].url).to.equal(url); expect(report[0].url).to.equal(`${url}/a`);
expect(report[0].body.id).to.equal('PrefixedRequestAnimationFrame'); expect(report[0].body.id).to.equal('PrefixedRequestAnimationFrame');
} finally { } finally {
bw.destroy(); bw.destroy();
@ -218,8 +216,7 @@ describe('web security', () => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end('<body>'); res.end('<body>');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
after(() => { after(() => {
server.close(); server.close();
@ -847,8 +844,7 @@ describe('chromium features', () => {
res.end(`body:${body}`); res.end(`body:${body}`);
}); });
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
after(async () => { after(async () => {
server.close(); server.close();
@ -1213,16 +1209,13 @@ describe('chromium features', () => {
let serverURL: string; let serverURL: string;
let server: any; let server: any;
beforeEach((done) => { beforeEach(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
res.writeHead(200); res.writeHead(200);
const filePath = path.join(fixturesPath, 'pages', 'window-opener-targetOrigin.html'); const filePath = path.join(fixturesPath, 'pages', 'window-opener-targetOrigin.html');
res.end(fs.readFileSync(filePath, 'utf8')); res.end(fs.readFileSync(filePath, 'utf8'));
}); });
server.listen(0, '127.0.0.1', () => { serverURL = (await listen(server)).url;
serverURL = `http://127.0.0.1:${server.address().port}`;
done();
});
}); });
afterEach(() => { afterEach(() => {
@ -1523,7 +1516,7 @@ describe('chromium features', () => {
let server: http.Server; let server: http.Server;
let serverUrl: string; let serverUrl: string;
let serverCrossSiteUrl: string; let serverCrossSiteUrl: string;
before((done) => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
const respond = () => { const respond = () => {
if (req.url === '/redirect-cross-site') { if (req.url === '/redirect-cross-site') {
@ -1538,11 +1531,8 @@ describe('chromium features', () => {
}; };
setTimeout(respond, 0); setTimeout(respond, 0);
}); });
server.listen(0, '127.0.0.1', () => { serverUrl = (await listen(server)).url;
serverUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`; serverCrossSiteUrl = serverUrl.replace('127.0.0.1', 'localhost');
serverCrossSiteUrl = `http://localhost:${(server.address() as AddressInfo).port}`;
done();
});
}); });
after(() => { after(() => {
@ -1935,8 +1925,7 @@ describe('chromium features', () => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end(''); res.end('');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
after(() => { after(() => {
server.close(); server.close();
@ -2057,8 +2046,7 @@ describe('chromium features', () => {
describe('websockets', () => { describe('websockets', () => {
it('has user agent', async () => { it('has user agent', async () => {
const server = http.createServer(); const server = http.createServer();
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
const wss = new ws.Server({ server: server }); const wss = new ws.Server({ server: server });
const finished = new Promise<string | undefined>((resolve, reject) => { const finished = new Promise<string | undefined>((resolve, reject) => {
wss.on('error', reject); wss.on('error', reject);
@ -2081,8 +2069,7 @@ describe('chromium features', () => {
res.end('test'); res.end('test');
}); });
defer(() => server.close()); defer(() => server.close());
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.loadURL(`file://${fixturesPath}/pages/blank.html`); w.loadURL(`file://${fixturesPath}/pages/blank.html`);
const x = await w.webContents.executeJavaScript(` const x = await w.webContents.executeJavaScript(`
@ -2268,7 +2255,9 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
const fullscreenChildHtml = promisify(fs.readFile)( const fullscreenChildHtml = promisify(fs.readFile)(
path.join(fixturesPath, 'pages', 'fullscreen-oopif.html') path.join(fixturesPath, 'pages', 'fullscreen-oopif.html')
); );
let w: BrowserWindow, server: http.Server; let w: BrowserWindow;
let server: http.Server;
let crossSiteUrl: string;
beforeEach(async () => { beforeEach(async () => {
server = http.createServer(async (_req, res) => { server = http.createServer(async (_req, res) => {
@ -2277,11 +2266,8 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
res.end(); res.end();
}); });
await new Promise<void>((resolve) => { const serverUrl = (await listen(server)).url;
server.listen(8989, '127.0.0.1', () => { crossSiteUrl = serverUrl.replace('127.0.0.1', 'localhost');
resolve();
});
});
w = new BrowserWindow({ w = new BrowserWindow({
show: true, show: true,
@ -2303,7 +2289,7 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
ifit(process.platform !== 'darwin')('can fullscreen from out-of-process iframes (non-macOS)', async () => { ifit(process.platform !== 'darwin')('can fullscreen from out-of-process iframes (non-macOS)', async () => {
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange'); const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
const html = const html =
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>'; `<iframe style="width: 0" frameborder=0 src="${crossSiteUrl}" allowfullscreen></iframe>`;
w.loadURL(`data:text/html,${html}`); w.loadURL(`data:text/html,${html}`);
await fullscreenChange; await fullscreenChange;
@ -2328,7 +2314,7 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
await emittedOnce(w, 'enter-full-screen'); await emittedOnce(w, 'enter-full-screen');
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange'); const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
const html = const html =
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>'; `<iframe style="width: 0" frameborder=0 src="${crossSiteUrl}" allowfullscreen></iframe>`;
w.loadURL(`data:text/html,${html}`); w.loadURL(`data:text/html,${html}`);
await fullscreenChange; await fullscreenChange;
@ -2791,8 +2777,7 @@ describe('navigator.hid', () => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end('<body>'); res.end('<body>');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
const requestDevices: any = () => { const requestDevices: any = () => {
@ -2990,8 +2975,7 @@ describe('navigator.usb', () => {
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.end('<body>'); res.end('<body>');
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); serverUrl = (await listen(server)).url;
serverUrl = `http://localhost:${(server.address() as any).port}`;
}); });
const requestDevices: any = () => { const requestDevices: any = () => {

View file

@ -2,12 +2,11 @@ import { expect } from 'chai';
import { app, session, BrowserWindow, ipcMain, WebContents, Extension, Session } from 'electron/main'; import { app, session, BrowserWindow, ipcMain, WebContents, Extension, Session } from 'electron/main';
import { closeAllWindows, closeWindow } from './lib/window-helpers'; import { closeAllWindows, closeWindow } from './lib/window-helpers';
import * as http from 'http'; import * as http from 'http';
import { AddressInfo } from 'net';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as WebSocket from 'ws'; import * as WebSocket from 'ws';
import { emittedOnce, emittedNTimes, emittedUntil } from './lib/events-helpers'; import { emittedOnce, emittedNTimes, emittedUntil } from './lib/events-helpers';
import { ifit } from './lib/spec-helpers'; import { ifit, listen } from './lib/spec-helpers';
const uuid = require('uuid'); const uuid = require('uuid');
@ -19,7 +18,7 @@ describe('chrome extensions', () => {
// NB. extensions are only allowed on http://, https:// and ftp:// (!) urls by default. // NB. extensions are only allowed on http://, https:// and ftp:// (!) urls by default.
let server: http.Server; let server: http.Server;
let url: string; let url: string;
let port: string; let port: number;
before(async () => { before(async () => {
server = http.createServer((req, res) => { server = http.createServer((req, res) => {
if (req.url === '/cors') { if (req.url === '/cors') {
@ -37,11 +36,7 @@ describe('chrome extensions', () => {
}); });
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', () => { ({ port, url } = await listen(server));
port = String((server.address() as AddressInfo).port);
url = `http://127.0.0.1:${port}`;
resolve();
}));
}); });
after(() => { after(() => {
server.close(); server.close();
@ -324,7 +319,7 @@ describe('chrome extensions', () => {
customSession.webRequest.onBeforeSendHeaders(() => { customSession.webRequest.onBeforeSendHeaders(() => {
resolve(); resolve();
}); });
await w.loadFile(path.join(fixtures, 'api', 'webrequest.html'), { query: { port } }); await w.loadFile(path.join(fixtures, 'api', 'webrequest.html'), { query: { port: `${port}` } });
await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-webRequest-wss')); await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-webRequest-wss'));
})(); })();
}); });
@ -332,7 +327,7 @@ describe('chrome extensions', () => {
describe('WebSocket', () => { describe('WebSocket', () => {
it('can be proxied', async () => { it('can be proxied', async () => {
await w.loadFile(path.join(fixtures, 'api', 'webrequest.html'), { query: { port } }); await w.loadFile(path.join(fixtures, 'api', 'webrequest.html'), { query: { port: `${port}` } });
await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-webRequest-wss')); await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-webRequest-wss'));
customSession.webRequest.onSendHeaders((details) => { customSession.webRequest.onSendHeaders((details) => {
if (details.url.startsWith('ws://')) { if (details.url.startsWith('ws://')) {

View file

@ -176,17 +176,16 @@ describe('webContents.setWindowOpenHandler', () => {
await emittedOnce(browserWindow.webContents, 'did-create-window'); await emittedOnce(browserWindow.webContents, 'did-create-window');
}); });
it('can change webPreferences of child windows', (done) => { it('can change webPreferences of child windows', async () => {
browserWindow.webContents.setWindowOpenHandler(() => ({ action: 'allow', overrideBrowserWindowOptions: { webPreferences: { defaultFontSize: 30 } } })); browserWindow.webContents.setWindowOpenHandler(() => ({ action: 'allow', overrideBrowserWindowOptions: { webPreferences: { defaultFontSize: 30 } } }));
browserWindow.webContents.on('did-create-window', async (childWindow) => { const didCreateWindow = emittedOnce(browserWindow.webContents, 'did-create-window');
browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
const [childWindow] = await didCreateWindow;
await childWindow.webContents.executeJavaScript("document.write('hello')"); await childWindow.webContents.executeJavaScript("document.write('hello')");
const size = await childWindow.webContents.executeJavaScript("getComputedStyle(document.querySelector('body')).fontSize"); const size = await childWindow.webContents.executeJavaScript("getComputedStyle(document.querySelector('body')).fontSize");
expect(size).to.equal('30px'); expect(size).to.equal('30px');
done();
});
browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
}); });
it('does not hang parent window when denying window.open', async () => { it('does not hang parent window when denying window.open', async () => {

View file

@ -1,7 +1,10 @@
import * as childProcess from 'child_process'; import * as childProcess from 'child_process';
import * as path from 'path'; import * as path from 'path';
import * as http from 'http'; import * as http from 'http';
import * as https from 'https';
import * as net from 'net';
import * as v8 from 'v8'; import * as v8 from 'v8';
import * as url from 'url';
import { SuiteFunction, TestFunction } from 'mocha'; import { SuiteFunction, TestFunction } from 'mocha';
import { BrowserWindow } from 'electron/main'; import { BrowserWindow } from 'electron/main';
import { AssertionError } from 'chai'; import { AssertionError } from 'chai';
@ -191,3 +194,11 @@ export async function itremote (name: string, fn: Function, args?: any[]) {
if (!ok) { throw new AssertionError(message); } if (!ok) { throw new AssertionError(message); }
}); });
} }
export async function listen (server: http.Server | https.Server) {
const hostname = '127.0.0.1';
await new Promise<void>(resolve => server.listen(0, hostname, () => resolve()));
const { port } = server.address() as net.AddressInfo;
const protocol = (server instanceof https.Server) ? 'https' : 'http';
return { port, url: url.format({ protocol, hostname, port }) };
}

View file

@ -7,9 +7,8 @@ import * as url from 'url';
import { BrowserWindow, WebPreferences } from 'electron/main'; import { BrowserWindow, WebPreferences } from 'electron/main';
import { closeWindow } from './lib/window-helpers'; import { closeWindow } from './lib/window-helpers';
import { AddressInfo } from 'net';
import { emittedUntil } from './lib/events-helpers'; import { emittedUntil } from './lib/events-helpers';
import { delay } from './lib/spec-helpers'; import { delay, listen } from './lib/spec-helpers';
const messageContainsSecurityWarning = (event: Event, level: number, message: string) => { const messageContainsSecurityWarning = (event: Event, level: number, message: string) => {
return message.indexOf('Electron Security Warning') > -1; return message.indexOf('Electron Security Warning') > -1;
@ -25,7 +24,7 @@ describe('security warnings', () => {
let useCsp = true; let useCsp = true;
let serverUrl: string; let serverUrl: string;
before((done) => { before(async () => {
// Create HTTP Server // Create HTTP Server
server = http.createServer((request, response) => { server = http.createServer((request, response) => {
const uri = url.parse(request.url!).pathname!; const uri = url.parse(request.url!).pathname!;
@ -57,10 +56,9 @@ describe('security warnings', () => {
response.end(); response.end();
}); });
}); });
}).listen(0, '127.0.0.1', () => {
serverUrl = `http://localhost2:${(server.address() as AddressInfo).port}`;
done();
}); });
serverUrl = `http://localhost2:${(await listen(server)).port}`;
}); });
after(() => { after(() => {

View file

@ -4,10 +4,9 @@ import { expect } from 'chai';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as http from 'http'; import * as http from 'http';
import { AddressInfo } from 'net';
import { closeWindow } from './lib/window-helpers'; import { closeWindow } from './lib/window-helpers';
import { emittedOnce } from './lib/events-helpers'; import { emittedOnce } from './lib/events-helpers';
import { ifit, ifdescribe, delay } from './lib/spec-helpers'; import { ifit, ifdescribe, delay, listen } from './lib/spec-helpers';
const features = process._linkedBinding('electron_common_features'); const features = process._linkedBinding('electron_common_features');
const v8Util = process._linkedBinding('electron_common_v8_util'); const v8Util = process._linkedBinding('electron_common_v8_util');
@ -57,8 +56,9 @@ ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', function ()
res.end(data); res.end(data);
}); });
}); });
before((done) => { let serverUrl: string;
server.listen(0, '127.0.0.1', () => done()); before(async () => {
serverUrl = (await listen(server)).url;
}); });
after(() => server.close()); after(() => server.close());
@ -77,7 +77,7 @@ ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', function ()
sandbox sandbox
} }
}); });
w.webContents.session.setSpellCheckerDictionaryDownloadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}/`); w.webContents.session.setSpellCheckerDictionaryDownloadURL(serverUrl);
w.webContents.session.setSpellCheckerLanguages(['en-US']); w.webContents.session.setSpellCheckerLanguages(['en-US']);
await w.loadFile(path.resolve(__dirname, './fixtures/chromium/spellchecker.html')); await w.loadFile(path.resolve(__dirname, './fixtures/chromium/spellchecker.html'));
}); });

View file

@ -3,10 +3,9 @@ import * as url from 'url';
import { BrowserWindow, session, ipcMain, app, WebContents } from 'electron/main'; import { BrowserWindow, session, ipcMain, app, WebContents } from 'electron/main';
import { closeAllWindows } from './lib/window-helpers'; import { closeAllWindows } from './lib/window-helpers';
import { emittedOnce, emittedUntil } from './lib/events-helpers'; import { emittedOnce, emittedUntil } from './lib/events-helpers';
import { ifit, ifdescribe, delay, defer, itremote, useRemoteContext } from './lib/spec-helpers'; import { ifit, ifdescribe, delay, defer, itremote, useRemoteContext, listen } from './lib/spec-helpers';
import { expect } from 'chai'; import { expect } from 'chai';
import * as http from 'http'; import * as http from 'http';
import { AddressInfo } from 'net';
import * as auth from 'basic-auth'; import * as auth from 'basic-auth';
declare let WebView: any; declare let WebView: any;
@ -1208,11 +1207,11 @@ describe('<webview> tag', function () {
res.end(); res.end();
server.close(); server.close();
} }
}).listen(0, '127.0.0.1', () => { });
const port = (server.address() as AddressInfo).port; listen(server).then(({ url }) => {
loadWebView(w, { loadWebView(w, {
httpreferrer: referrer, httpreferrer: referrer,
src: `http://127.0.0.1:${port}` src: url
}); });
}); });
}); });
@ -1464,15 +1463,13 @@ describe('<webview> tag', function () {
res.end(); res.end();
} }
}); });
const uri = await new Promise<string>(resolve => server.listen(0, '127.0.0.1', () => { const { url } = await listen(server);
resolve(`http://127.0.0.1:${(server.address() as AddressInfo).port}`);
}));
defer(() => { server.close(); }); defer(() => { server.close(); });
const event = await loadWebViewAndWaitForEvent(w, { const event = await loadWebViewAndWaitForEvent(w, {
src: `${uri}/302` src: `${url}/302`
}, 'did-redirect-navigation'); }, 'did-redirect-navigation');
expect(event.url).to.equal(`${uri}/200`); expect(event.url).to.equal(`${url}/200`);
expect(event.isInPlace).to.be.false(); expect(event.isInPlace).to.be.false();
expect(event.isMainFrame).to.be.true(); expect(event.isMainFrame).to.be.true();
expect(event.frameProcessId).to.be.a('number'); expect(event.frameProcessId).to.be.a('number');
@ -1572,8 +1569,7 @@ describe('<webview> tag', function () {
describe('dom-ready event', () => { describe('dom-ready event', () => {
it('emits when document is loaded', async () => { it('emits when document is loaded', async () => {
const server = http.createServer(() => {}); const server = http.createServer(() => {});
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
await loadWebViewAndWaitForEvent(w, { await loadWebViewAndWaitForEvent(w, {
src: `file://${fixtures}/pages/dom-ready.html?port=${port}` src: `file://${fixtures}/pages/dom-ready.html?port=${port}`
}, 'dom-ready'); }, 'dom-ready');
@ -2063,8 +2059,7 @@ describe('<webview> tag', function () {
defer(() => { defer(() => {
server.close(); server.close();
}); });
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve)); const { port } = await listen(server);
const port = (server.address() as AddressInfo).port;
const e = await loadWebViewAndWaitForEvent(w, { const e = await loadWebViewAndWaitForEvent(w, {
nodeintegration: 'on', nodeintegration: 'on',
webpreferences: 'contextIsolation=no', webpreferences: 'contextIsolation=no',