test: make sure tests fail properly instead of timing out (#24316)
This commit is contained in:
parent
451086d7f2
commit
c6db47182a
20 changed files with 1484 additions and 1367 deletions
|
@ -209,21 +209,17 @@ describe('app module', () => {
|
|||
});
|
||||
|
||||
describe('app.requestSingleInstanceLock', () => {
|
||||
it('prevents the second launch of app', function (done) {
|
||||
it('prevents the second launch of app', async function () {
|
||||
this.timeout(120000);
|
||||
const appPath = path.join(fixturesPath, 'api', 'singleton');
|
||||
const first = cp.spawn(process.execPath, [appPath]);
|
||||
first.once('exit', code => {
|
||||
expect(code).to.equal(0);
|
||||
});
|
||||
await emittedOnce(first.stdout, 'data');
|
||||
// Start second app when received output.
|
||||
first.stdout.once('data', () => {
|
||||
const second = cp.spawn(process.execPath, [appPath]);
|
||||
second.once('exit', code => {
|
||||
expect(code).to.equal(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
const [code2] = await emittedOnce(second, 'exit');
|
||||
expect(code2).to.equal(1);
|
||||
const [code1] = await emittedOnce(first, 'exit');
|
||||
expect(code1).to.equal(0);
|
||||
});
|
||||
|
||||
it('passes arguments to the second-instance event', async () => {
|
||||
|
@ -1003,34 +999,28 @@ describe('app module', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('does not launch for argument following a URL', done => {
|
||||
it('does not launch for argument following a URL', async () => {
|
||||
const appPath = path.join(fixturesPath, 'api', 'quit-app');
|
||||
// App should exit with non 123 code.
|
||||
const first = cp.spawn(process.execPath, [appPath, 'electron-test:?', 'abc']);
|
||||
first.once('exit', code => {
|
||||
const [code] = await emittedOnce(first, 'exit');
|
||||
expect(code).to.not.equal(123);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('launches successfully for argument following a file path', done => {
|
||||
it('launches successfully for argument following a file path', async () => {
|
||||
const appPath = path.join(fixturesPath, 'api', 'quit-app');
|
||||
// App should exit with code 123.
|
||||
const first = cp.spawn(process.execPath, [appPath, 'e:\\abc', 'abc']);
|
||||
first.once('exit', code => {
|
||||
const [code] = await emittedOnce(first, 'exit');
|
||||
expect(code).to.equal(123);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('launches successfully for multiple URIs following --', done => {
|
||||
it('launches successfully for multiple URIs following --', async () => {
|
||||
const appPath = path.join(fixturesPath, 'api', 'quit-app');
|
||||
// App should exit with code 123.
|
||||
const first = cp.spawn(process.execPath, [appPath, '--', 'http://electronjs.org', 'electron-test://testdata']);
|
||||
first.once('exit', code => {
|
||||
const [code] = await emittedOnce(first, 'exit');
|
||||
expect(code).to.equal(123);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { autoUpdater } from 'electron/main';
|
||||
import { expect } from 'chai';
|
||||
import { ifit, ifdescribe } from './spec-helpers';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
|
||||
ifdescribe(!process.mas)('autoUpdater module', function () {
|
||||
describe('checkForUpdates', function () {
|
||||
ifit(process.platform === 'win32')('emits an error on Windows if the feed URL is not set', function (done) {
|
||||
autoUpdater.once('error', function (error) {
|
||||
expect(error.message).to.equal('Update URL is not set');
|
||||
done();
|
||||
});
|
||||
ifit(process.platform === 'win32')('emits an error on Windows if the feed URL is not set', async function () {
|
||||
const errorEvent = emittedOnce(autoUpdater, 'error');
|
||||
autoUpdater.setFeedURL({ url: '' });
|
||||
autoUpdater.checkForUpdates();
|
||||
const [error] = await errorEvent;
|
||||
expect(error.message).to.equal('Update URL is not set');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -19,11 +19,10 @@ ifdescribe(!process.mas)('autoUpdater module', function () {
|
|||
expect(autoUpdater.getFeedURL()).to.equal('');
|
||||
});
|
||||
|
||||
ifit(process.platform === 'win32')('correctly fetches the previously set FeedURL', function (done) {
|
||||
ifit(process.platform === 'win32')('correctly fetches the previously set FeedURL', function () {
|
||||
const updateURL = 'https://fake-update.electron.io';
|
||||
autoUpdater.setFeedURL({ url: updateURL });
|
||||
expect(autoUpdater.getFeedURL()).to.equal(updateURL);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -56,12 +55,11 @@ ifdescribe(!process.mas)('autoUpdater module', function () {
|
|||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('on Mac', function () {
|
||||
it('emits an error when the application is unsigned', done => {
|
||||
autoUpdater.once('error', function (error) {
|
||||
expect(error.message).equal('Could not get code signature for running application');
|
||||
done();
|
||||
});
|
||||
it('emits an error when the application is unsigned', async () => {
|
||||
const errorEvent = emittedOnce(autoUpdater, 'error');
|
||||
autoUpdater.setFeedURL({ url: '' });
|
||||
const [error] = await errorEvent;
|
||||
expect(error.message).equal('Could not get code signature for running application');
|
||||
});
|
||||
|
||||
it('does not throw if default is the serverType', () => {
|
||||
|
@ -81,12 +79,11 @@ ifdescribe(!process.mas)('autoUpdater module', function () {
|
|||
});
|
||||
|
||||
describe('quitAndInstall', () => {
|
||||
ifit(process.platform === 'win32')('emits an error on Windows when no update is available', function (done) {
|
||||
autoUpdater.once('error', function (error) {
|
||||
expect(error.message).to.equal('No update available, can\'t quit and install');
|
||||
done();
|
||||
});
|
||||
ifit(process.platform === 'win32')('emits an error on Windows when no update is available', async function () {
|
||||
const errorEvent = emittedOnce(autoUpdater, 'error');
|
||||
autoUpdater.quitAndInstall();
|
||||
const [error] = await errorEvent;
|
||||
expect(error.message).to.equal('No update available, can\'t quit and install');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -233,17 +233,16 @@ describe('BrowserView module', () => {
|
|||
});
|
||||
|
||||
describe('window.open()', () => {
|
||||
it('works in BrowserView', (done) => {
|
||||
it('works in BrowserView', async () => {
|
||||
view = new BrowserView();
|
||||
w.setBrowserView(view);
|
||||
view.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures) => {
|
||||
e.preventDefault();
|
||||
const newWindow = emittedOnce(view.webContents, 'new-window');
|
||||
view.webContents.once('new-window', event => event.preventDefault());
|
||||
view.webContents.loadFile(path.join(fixtures, 'pages', 'window-open.html'));
|
||||
const [, url, frameName,,, additionalFeatures] = await newWindow;
|
||||
expect(url).to.equal('http://host/');
|
||||
expect(frameName).to.equal('host');
|
||||
expect(additionalFeatures[0]).to.equal('this-is-not-a-standard-feature');
|
||||
done();
|
||||
});
|
||||
view.webContents.loadFile(path.join(fixtures, 'pages', 'window-open.html'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@ import * as path from 'path';
|
|||
import { AddressInfo } from 'net';
|
||||
import { BrowserWindow } from 'electron/main';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
import { emittedOnce, emittedUntil } from './events-helpers';
|
||||
|
||||
describe('debugger module', () => {
|
||||
const fixtures = path.resolve(__dirname, '..', 'spec', 'fixtures');
|
||||
|
@ -21,18 +21,11 @@ describe('debugger module', () => {
|
|||
afterEach(closeAllWindows);
|
||||
|
||||
describe('debugger.attach', () => {
|
||||
it('succeeds when devtools is already open', done => {
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
it('succeeds when devtools is already open', async () => {
|
||||
await w.webContents.loadURL('about:blank');
|
||||
w.webContents.openDevTools();
|
||||
try {
|
||||
w.webContents.debugger.attach();
|
||||
} catch (err) {
|
||||
done(`unexpected error : ${err}`);
|
||||
}
|
||||
expect(w.webContents.debugger.isAttached()).to.be.true();
|
||||
done();
|
||||
});
|
||||
w.webContents.loadURL('about:blank');
|
||||
});
|
||||
|
||||
it('fails when protocol version is not supported', done => {
|
||||
|
@ -44,49 +37,33 @@ describe('debugger module', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('attaches when no protocol version is specified', done => {
|
||||
try {
|
||||
it('attaches when no protocol version is specified', async () => {
|
||||
w.webContents.debugger.attach();
|
||||
} catch (err) {
|
||||
done(`unexpected error : ${err}`);
|
||||
}
|
||||
expect(w.webContents.debugger.isAttached()).to.be.true();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('debugger.detach', () => {
|
||||
it('fires detach event', (done) => {
|
||||
w.webContents.debugger.on('detach', (e, reason) => {
|
||||
it('fires detach event', async () => {
|
||||
const detach = emittedOnce(w.webContents.debugger, 'detach');
|
||||
w.webContents.debugger.attach();
|
||||
w.webContents.debugger.detach();
|
||||
const [, reason] = await detach;
|
||||
expect(reason).to.equal('target closed');
|
||||
expect(w.webContents.debugger.isAttached()).to.be.false();
|
||||
done();
|
||||
});
|
||||
|
||||
try {
|
||||
w.webContents.debugger.attach();
|
||||
} catch (err) {
|
||||
done(`unexpected error : ${err}`);
|
||||
}
|
||||
w.webContents.debugger.detach();
|
||||
});
|
||||
|
||||
it('doesn\'t disconnect an active devtools session', done => {
|
||||
it('doesn\'t disconnect an active devtools session', async () => {
|
||||
w.webContents.loadURL('about:blank');
|
||||
try {
|
||||
const detach = emittedOnce(w.webContents.debugger, 'detach');
|
||||
w.webContents.debugger.attach();
|
||||
} catch (err) {
|
||||
return done(`unexpected error : ${err}`);
|
||||
}
|
||||
w.webContents.openDevTools();
|
||||
w.webContents.once('devtools-opened', () => {
|
||||
w.webContents.debugger.detach();
|
||||
});
|
||||
w.webContents.debugger.on('detach', () => {
|
||||
await detach;
|
||||
expect(w.webContents.debugger.isAttached()).to.be.false();
|
||||
expect((w as any).devToolsWebContents.isDestroyed()).to.be.false();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -130,33 +107,20 @@ describe('debugger module', () => {
|
|||
w.webContents.debugger.detach();
|
||||
});
|
||||
|
||||
it('fires message event', done => {
|
||||
it('fires message event', async () => {
|
||||
const url = process.platform !== 'win32'
|
||||
? `file://${path.join(fixtures, 'pages', 'a.html')}`
|
||||
: `file:///${path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/')}`;
|
||||
w.webContents.loadURL(url);
|
||||
|
||||
try {
|
||||
w.webContents.debugger.attach();
|
||||
} catch (err) {
|
||||
done(`unexpected error : ${err}`);
|
||||
}
|
||||
|
||||
w.webContents.debugger.on('message', (e, method, params) => {
|
||||
if (method === 'Console.messageAdded') {
|
||||
try {
|
||||
expect(params.message.level).to.equal('log');
|
||||
expect(params.message.url).to.equal(url);
|
||||
expect(params.message.text).to.equal('a');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
} finally {
|
||||
w.webContents.debugger.detach();
|
||||
}
|
||||
}
|
||||
});
|
||||
const message = emittedUntil(w.webContents.debugger, 'message',
|
||||
(event: Electron.Event, method: string) => method === 'Console.messageAdded');
|
||||
w.webContents.debugger.sendCommand('Console.enable');
|
||||
const [,, params] = await message;
|
||||
w.webContents.debugger.detach();
|
||||
expect((params as any).message.level).to.equal('log');
|
||||
expect((params as any).message.url).to.equal(url);
|
||||
expect((params as any).message.text).to.equal('a');
|
||||
});
|
||||
|
||||
it('returns error message when command fails', async () => {
|
||||
|
|
|
@ -43,9 +43,13 @@ describe('MenuItems', () => {
|
|||
const menu = Menu.buildFromTemplate([{
|
||||
label: 'text',
|
||||
click: (item) => {
|
||||
try {
|
||||
expect(item.constructor.name).to.equal('MenuItem');
|
||||
expect(item.label).to.equal('text');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
menu._executeCommand({}, menu.items[0].commandId);
|
||||
|
|
|
@ -305,8 +305,12 @@ describe('protocol module', () => {
|
|||
|
||||
it('can access request headers', (done) => {
|
||||
protocol.registerHttpProtocol(protocolName, (request) => {
|
||||
try {
|
||||
expect(request).to.have.property('headers');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
ajax(protocolName + '://fake-host');
|
||||
});
|
||||
|
@ -597,8 +601,12 @@ describe('protocol module', () => {
|
|||
|
||||
it('can access request headers', (done) => {
|
||||
protocol.interceptHttpProtocol('http', (request) => {
|
||||
try {
|
||||
expect(request).to.have.property('headers');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
ajax('http://fake-host');
|
||||
});
|
||||
|
|
|
@ -344,7 +344,7 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
|||
});
|
||||
|
||||
describe('remote objects registry', () => {
|
||||
it('does not dereference until the render view is deleted (regression)', (done) => {
|
||||
it('does not dereference until the render view is deleted (regression)', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
|
@ -353,12 +353,10 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
|||
}
|
||||
});
|
||||
|
||||
ipcMain.once('error-message', (event, message) => {
|
||||
expect(message).to.match(/^Cannot call method 'getURL' on missing remote object/);
|
||||
done();
|
||||
});
|
||||
|
||||
const message = emittedOnce(ipcMain, 'error-message');
|
||||
w.loadFile(path.join(fixtures, 'api', 'render-view-deleted.html'));
|
||||
const [, msg] = await message;
|
||||
expect(msg).to.match(/^Cannot call method 'getURL' on missing remote object/);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -423,16 +423,24 @@ describe('session module', () => {
|
|||
</html>`;
|
||||
|
||||
protocol.registerStringProtocol(scheme, (request, callback) => {
|
||||
try {
|
||||
if (request.method === 'GET') {
|
||||
callback({ data: content, mimeType: 'text/html' });
|
||||
} else if (request.method === 'POST') {
|
||||
const uuid = request.uploadData![1].blobUUID;
|
||||
expect(uuid).to.be.a('string');
|
||||
session.defaultSession.getBlobData(uuid!).then(result => {
|
||||
try {
|
||||
expect(result.toString()).to.equal(postData);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadURL(url);
|
||||
|
@ -618,8 +626,12 @@ describe('session module', () => {
|
|||
session.defaultSession.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
try {
|
||||
assertDownload(state, item);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
session.defaultSession.downloadURL(`${url}:${port}`);
|
||||
|
@ -631,8 +643,12 @@ describe('session module', () => {
|
|||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
try {
|
||||
assertDownload(state, item);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
w.webContents.downloadURL(`${url}:${port}`);
|
||||
|
@ -649,8 +665,12 @@ describe('session module', () => {
|
|||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
try {
|
||||
assertDownload(state, item, true);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
w.webContents.downloadURL(`${protocolName}://item`);
|
||||
|
@ -687,6 +707,7 @@ describe('session module', () => {
|
|||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
try {
|
||||
expect(state).to.equal('cancelled');
|
||||
expect(item.getFilename()).to.equal('mock.pdf');
|
||||
expect(item.getMimeType()).to.equal('application/pdf');
|
||||
|
@ -694,6 +715,9 @@ describe('session module', () => {
|
|||
expect(item.getTotalBytes()).to.equal(mockPDF.length);
|
||||
expect(item.getContentDisposition()).to.equal(contentDisposition);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
item.cancel();
|
||||
});
|
||||
|
@ -712,8 +736,12 @@ describe('session module', () => {
|
|||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function () {
|
||||
try {
|
||||
expect(item.getFilename()).to.equal('download.pdf');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
item.cancel();
|
||||
});
|
||||
|
@ -744,8 +772,12 @@ describe('session module', () => {
|
|||
item.setSavePath(filePath);
|
||||
item.setSaveDialogOptions(options);
|
||||
item.on('done', function () {
|
||||
try {
|
||||
expect(item.getSaveDialogOptions()).to.deep.equal(options);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
item.cancel();
|
||||
});
|
||||
|
@ -761,8 +793,12 @@ describe('session module', () => {
|
|||
item.resume();
|
||||
}
|
||||
item.on('done', function (e, state) {
|
||||
try {
|
||||
expect(state).to.equal('interrupted');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
w.webContents.downloadURL(`file://${path.join(__dirname, 'does-not-exist.txt')}`);
|
||||
|
|
|
@ -8,7 +8,7 @@ import { BrowserWindow, ipcMain, webContents, session, WebContents, app } from '
|
|||
import { clipboard } from 'electron/common';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import { ifdescribe, ifit, delay } from './spec-helpers';
|
||||
import { ifdescribe, ifit, delay, defer } from './spec-helpers';
|
||||
|
||||
const pdfjs = require('pdfjs-dist');
|
||||
const fixturesPath = path.resolve(__dirname, '..', 'spec', 'fixtures');
|
||||
|
@ -223,29 +223,23 @@ describe('webContents module', () => {
|
|||
server.close();
|
||||
});
|
||||
|
||||
it('works after page load and during subframe load', (done) => {
|
||||
w.webContents.once('did-finish-load', () => {
|
||||
it('works after page load and during subframe load', async () => {
|
||||
await w.loadURL(serverUrl);
|
||||
// initiate a sub-frame load, then try and execute script during it
|
||||
w.webContents.executeJavaScript(`
|
||||
await w.webContents.executeJavaScript(`
|
||||
var iframe = document.createElement('iframe')
|
||||
iframe.src = '${serverUrl}/slow'
|
||||
document.body.appendChild(iframe)
|
||||
null // don't return the iframe
|
||||
`).then(() => {
|
||||
w.webContents.executeJavaScript('console.log(\'hello\')').then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
w.loadURL(serverUrl);
|
||||
`);
|
||||
await w.webContents.executeJavaScript('console.log(\'hello\')');
|
||||
});
|
||||
|
||||
it('executes after page load', (done) => {
|
||||
w.webContents.executeJavaScript('(() => "test")()').then(result => {
|
||||
expect(result).to.equal('test');
|
||||
done();
|
||||
});
|
||||
it('executes after page load', async () => {
|
||||
const executeJavaScript = w.webContents.executeJavaScript('(() => "test")()');
|
||||
w.loadURL(serverUrl);
|
||||
const result = await executeJavaScript;
|
||||
expect(result).to.equal('test');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -467,13 +461,11 @@ describe('webContents module', () => {
|
|||
|
||||
describe('getWebPreferences() API', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('should not crash when called for devTools webContents', (done) => {
|
||||
it('should not crash when called for devTools webContents', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.webContents.openDevTools();
|
||||
w.webContents.once('devtools-opened', () => {
|
||||
await emittedOnce(w.webContents, 'devtools-opened');
|
||||
expect(w.webContents.devToolsWebContents!.getWebPreferences()).to.be.null();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -652,71 +644,66 @@ describe('webContents module', () => {
|
|||
});
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('can send keydown events', (done) => {
|
||||
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
|
||||
it('can send keydown events', async () => {
|
||||
const keydown = emittedOnce(ipcMain, 'keydown');
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
|
||||
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
|
||||
expect(key).to.equal('a');
|
||||
expect(code).to.equal('KeyA');
|
||||
expect(keyCode).to.equal(65);
|
||||
expect(shiftKey).to.be.false();
|
||||
expect(ctrlKey).to.be.false();
|
||||
expect(altKey).to.be.false();
|
||||
done();
|
||||
});
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
|
||||
});
|
||||
|
||||
it('can send keydown events with modifiers', (done) => {
|
||||
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
|
||||
it('can send keydown events with modifiers', async () => {
|
||||
const keydown = emittedOnce(ipcMain, 'keydown');
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
|
||||
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
|
||||
expect(key).to.equal('Z');
|
||||
expect(code).to.equal('KeyZ');
|
||||
expect(keyCode).to.equal(90);
|
||||
expect(shiftKey).to.be.true();
|
||||
expect(ctrlKey).to.be.true();
|
||||
expect(altKey).to.be.false();
|
||||
done();
|
||||
});
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
|
||||
});
|
||||
|
||||
it('can send keydown events with special keys', (done) => {
|
||||
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
|
||||
it('can send keydown events with special keys', async () => {
|
||||
const keydown = emittedOnce(ipcMain, 'keydown');
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Tab', modifiers: ['alt'] });
|
||||
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
|
||||
expect(key).to.equal('Tab');
|
||||
expect(code).to.equal('Tab');
|
||||
expect(keyCode).to.equal(9);
|
||||
expect(shiftKey).to.be.false();
|
||||
expect(ctrlKey).to.be.false();
|
||||
expect(altKey).to.be.true();
|
||||
done();
|
||||
});
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Tab', modifiers: ['alt'] });
|
||||
});
|
||||
|
||||
it('can send char events', (done) => {
|
||||
ipcMain.once('keypress', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
|
||||
it('can send char events', async () => {
|
||||
const keypress = emittedOnce(ipcMain, 'keypress');
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
|
||||
w.webContents.sendInputEvent({ type: 'char', keyCode: 'A' });
|
||||
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keypress;
|
||||
expect(key).to.equal('a');
|
||||
expect(code).to.equal('KeyA');
|
||||
expect(keyCode).to.equal(65);
|
||||
expect(shiftKey).to.be.false();
|
||||
expect(ctrlKey).to.be.false();
|
||||
expect(altKey).to.be.false();
|
||||
done();
|
||||
});
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
|
||||
w.webContents.sendInputEvent({ type: 'char', keyCode: 'A' });
|
||||
});
|
||||
|
||||
it('can send char events with modifiers', (done) => {
|
||||
ipcMain.once('keypress', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
|
||||
it('can send char events with modifiers', async () => {
|
||||
const keypress = emittedOnce(ipcMain, 'keypress');
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z' });
|
||||
w.webContents.sendInputEvent({ type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
|
||||
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keypress;
|
||||
expect(key).to.equal('Z');
|
||||
expect(code).to.equal('KeyZ');
|
||||
expect(keyCode).to.equal(90);
|
||||
expect(shiftKey).to.be.true();
|
||||
expect(ctrlKey).to.be.true();
|
||||
expect(altKey).to.be.false();
|
||||
done();
|
||||
});
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z' });
|
||||
w.webContents.sendInputEvent({ type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -953,6 +940,7 @@ describe('webContents module', () => {
|
|||
e.sender.send(`${host}-zoom-set`);
|
||||
});
|
||||
ipcMain.on('host1-zoom-level', (e) => {
|
||||
try {
|
||||
const zoomLevel = e.sender.getZoomLevel();
|
||||
const expectedZoomLevel = hostZoomMap.host1;
|
||||
expect(zoomLevel).to.equal(expectedZoomLevel);
|
||||
|
@ -961,38 +949,45 @@ describe('webContents module', () => {
|
|||
} else {
|
||||
w.loadURL(`${scheme}://host2`);
|
||||
}
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
ipcMain.once('host2-zoom-level', (e) => {
|
||||
try {
|
||||
const zoomLevel = e.sender.getZoomLevel();
|
||||
const expectedZoomLevel = hostZoomMap.host2;
|
||||
expect(zoomLevel).to.equal(expectedZoomLevel);
|
||||
finalNavigation = true;
|
||||
w.webContents.goBack();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
w.loadURL(`${scheme}://host1`);
|
||||
});
|
||||
|
||||
it('can propagate zoom level across same session', (done) => {
|
||||
it('can propagate zoom level across same session', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
|
||||
const w2 = new BrowserWindow({ show: false });
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
|
||||
defer(() => {
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
});
|
||||
|
||||
await w.loadURL(`${scheme}://host3`);
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
|
||||
await w2.loadURL(`${scheme}://host3`);
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(hostZoomMap.host3);
|
||||
|
||||
const zoomLevel2 = w2.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(zoomLevel2);
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
done();
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
w2.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
w.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
|
||||
it('cannot propagate zoom level across different session', (done) => {
|
||||
it('cannot propagate zoom level across different session', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
|
||||
const w2 = new BrowserWindow({
|
||||
show: false,
|
||||
|
@ -1004,7 +999,16 @@ describe('webContents module', () => {
|
|||
protocol.registerStringProtocol(scheme, (request, callback) => {
|
||||
callback('hello');
|
||||
});
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
|
||||
defer(() => {
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
});
|
||||
|
||||
await w.loadURL(`${scheme}://host3`);
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
|
||||
await w2.loadURL(`${scheme}://host3`);
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(hostZoomMap.host3);
|
||||
|
||||
|
@ -1013,15 +1017,6 @@ describe('webContents module', () => {
|
|||
expect(zoomLevel1).to.not.equal(zoomLevel2);
|
||||
|
||||
protocol.unregisterProtocol(scheme);
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
done();
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
w2.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
w.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
|
||||
it('can persist when it contains iframe', (done) => {
|
||||
|
@ -1036,12 +1031,17 @@ describe('webContents module', () => {
|
|||
const content = `<iframe src=${url}></iframe>`;
|
||||
w.webContents.on('did-frame-finish-load', (e, isMainFrame) => {
|
||||
if (!isMainFrame) {
|
||||
try {
|
||||
const zoomLevel = w.webContents.zoomLevel;
|
||||
expect(zoomLevel).to.equal(2.0);
|
||||
|
||||
w.webContents.zoomLevel = 0;
|
||||
server.close();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
w.webContents.on('dom-ready', () => {
|
||||
|
@ -1051,30 +1051,25 @@ describe('webContents module', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('cannot propagate when used with webframe', (done) => {
|
||||
it('cannot propagate when used with webframe', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
|
||||
let finalZoomLevel = 0;
|
||||
const w2 = new BrowserWindow({
|
||||
show: false
|
||||
});
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(finalZoomLevel);
|
||||
const w2 = new BrowserWindow({ show: false });
|
||||
|
||||
const temporaryZoomSet = emittedOnce(ipcMain, 'temporary-zoom-set');
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'webframe-zoom.html'));
|
||||
await temporaryZoomSet;
|
||||
|
||||
const finalZoomLevel = w.webContents.getZoomLevel();
|
||||
await w2.loadFile(path.join(fixturesPath, 'pages', 'c.html'));
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
const zoomLevel2 = w2.webContents.zoomLevel;
|
||||
expect(zoomLevel2).to.equal(0);
|
||||
expect(zoomLevel1).to.not.equal(zoomLevel2);
|
||||
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
done();
|
||||
});
|
||||
ipcMain.once('temporary-zoom-set', (e) => {
|
||||
const zoomLevel = e.sender.getZoomLevel();
|
||||
w2.loadFile(path.join(fixturesPath, 'pages', 'c.html'));
|
||||
finalZoomLevel = zoomLevel;
|
||||
});
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'webframe-zoom.html'));
|
||||
|
||||
expect(zoomLevel1).to.equal(finalZoomLevel);
|
||||
expect(zoomLevel2).to.equal(0);
|
||||
expect(zoomLevel1).to.not.equal(zoomLevel2);
|
||||
});
|
||||
|
||||
describe('with unique domains', () => {
|
||||
|
@ -1168,13 +1163,9 @@ describe('webContents module', () => {
|
|||
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('does not emit current-render-view-deleted when speculative RVHs are deleted', (done) => {
|
||||
it('does not emit current-render-view-deleted when speculative RVHs are deleted', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
let currentRenderViewDeletedEmitted = false;
|
||||
w.webContents.once('destroyed', () => {
|
||||
expect(currentRenderViewDeletedEmitted).to.be.false('current-render-view-deleted was emitted');
|
||||
done();
|
||||
});
|
||||
const renderViewDeletedHandler = () => {
|
||||
currentRenderViewDeletedEmitted = true;
|
||||
};
|
||||
|
@ -1183,40 +1174,41 @@ describe('webContents module', () => {
|
|||
w.webContents.removeListener('current-render-view-deleted' as any, renderViewDeletedHandler);
|
||||
w.close();
|
||||
});
|
||||
const destroyed = emittedOnce(w.webContents, 'destroyed');
|
||||
w.loadURL(`${serverUrl}/redirect-cross-site`);
|
||||
await destroyed;
|
||||
expect(currentRenderViewDeletedEmitted).to.be.false('current-render-view-deleted was emitted');
|
||||
});
|
||||
|
||||
it('emits current-render-view-deleted if the current RVHs are deleted', (done) => {
|
||||
it('emits current-render-view-deleted if the current RVHs are deleted', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
let currentRenderViewDeletedEmitted = false;
|
||||
w.webContents.once('destroyed', () => {
|
||||
expect(currentRenderViewDeletedEmitted).to.be.true('current-render-view-deleted wasn\'t emitted');
|
||||
done();
|
||||
});
|
||||
w.webContents.on('current-render-view-deleted' as any, () => {
|
||||
currentRenderViewDeletedEmitted = true;
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.close();
|
||||
});
|
||||
const destroyed = emittedOnce(w.webContents, 'destroyed');
|
||||
w.loadURL(`${serverUrl}/redirect-cross-site`);
|
||||
await destroyed;
|
||||
expect(currentRenderViewDeletedEmitted).to.be.true('current-render-view-deleted wasn\'t emitted');
|
||||
});
|
||||
|
||||
it('emits render-view-deleted if any RVHs are deleted', (done) => {
|
||||
it('emits render-view-deleted if any RVHs are deleted', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
let rvhDeletedCount = 0;
|
||||
w.webContents.once('destroyed', () => {
|
||||
const expectedRenderViewDeletedEventCount = 1;
|
||||
expect(rvhDeletedCount).to.equal(expectedRenderViewDeletedEventCount, 'render-view-deleted wasn\'t emitted the expected nr. of times');
|
||||
done();
|
||||
});
|
||||
w.webContents.on('render-view-deleted' as any, () => {
|
||||
rvhDeletedCount++;
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.close();
|
||||
});
|
||||
const destroyed = emittedOnce(w.webContents, 'destroyed');
|
||||
w.loadURL(`${serverUrl}/redirect-cross-site`);
|
||||
await destroyed;
|
||||
const expectedRenderViewDeletedEventCount = 1;
|
||||
expect(rvhDeletedCount).to.equal(expectedRenderViewDeletedEventCount, 'render-view-deleted wasn\'t emitted the expected nr. of times');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1304,6 +1296,7 @@ describe('webContents module', () => {
|
|||
const w = new BrowserWindow({ show: true });
|
||||
let count = 0;
|
||||
w.webContents.on('did-change-theme-color', (e, color) => {
|
||||
try {
|
||||
if (count === 0) {
|
||||
count += 1;
|
||||
expect(color).to.equal('#FFEEDD');
|
||||
|
@ -1312,6 +1305,9 @@ describe('webContents module', () => {
|
|||
expect(color).to.be.null();
|
||||
done();
|
||||
}
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'theme-color.html'));
|
||||
});
|
||||
|
@ -1374,9 +1370,14 @@ describe('webContents module', () => {
|
|||
const w = new BrowserWindow({ show: false });
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.url === '/should_have_referrer') {
|
||||
try {
|
||||
expect(req.headers.referer).to.equal(`http://127.0.0.1:${(server.address() as AddressInfo).port}/`);
|
||||
server.close();
|
||||
return done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
res.end('<a id="a" href="/should_have_referrer" target="_blank">link</a>');
|
||||
});
|
||||
|
@ -1399,8 +1400,12 @@ describe('webContents module', () => {
|
|||
const w = new BrowserWindow({ show: false });
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.url === '/should_have_referrer') {
|
||||
try {
|
||||
expect(req.headers.referer).to.equal(`http://127.0.0.1:${(server.address() as AddressInfo).port}/`);
|
||||
return done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
}
|
||||
res.end('');
|
||||
});
|
||||
|
@ -1640,8 +1645,7 @@ describe('webContents module', () => {
|
|||
});
|
||||
|
||||
it('respects custom settings', async () => {
|
||||
w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf.html'));
|
||||
await emittedOnce(w.webContents, 'did-finish-load');
|
||||
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf.html'));
|
||||
|
||||
const data = await w.webContents.printToPDF({
|
||||
pageRanges: {
|
||||
|
@ -1676,15 +1680,12 @@ describe('webContents module', () => {
|
|||
|
||||
describe('PictureInPicture video', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('works as expected', (done) => {
|
||||
it('works as expected', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
|
||||
w.webContents.once('did-finish-load', async () => {
|
||||
await w.loadFile(path.join(fixturesPath, 'api', 'picture-in-picture.html'));
|
||||
const result = await w.webContents.executeJavaScript(
|
||||
`runTest(${features.isPictureInPictureEnabled()})`, true);
|
||||
expect(result).to.be.true();
|
||||
done();
|
||||
});
|
||||
w.loadFile(path.join(fixturesPath, 'api', 'picture-in-picture.html'));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { expect } from 'chai';
|
|||
import * as path from 'path';
|
||||
import { BrowserWindow, ipcMain } from 'electron/main';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
|
||||
describe('asar package', () => {
|
||||
const fixtures = path.join(__dirname, '..', 'spec', 'fixtures');
|
||||
|
@ -10,7 +11,7 @@ describe('asar package', () => {
|
|||
afterEach(closeAllWindows);
|
||||
|
||||
describe('asar protocol', () => {
|
||||
it('sets __dirname correctly', function (done) {
|
||||
it('sets __dirname correctly', async function () {
|
||||
after(function () {
|
||||
ipcMain.removeAllListeners('dirname');
|
||||
});
|
||||
|
@ -24,14 +25,13 @@ describe('asar package', () => {
|
|||
}
|
||||
});
|
||||
const p = path.resolve(asarDir, 'web.asar', 'index.html');
|
||||
ipcMain.once('dirname', function (event, dirname) {
|
||||
expect(dirname).to.equal(path.dirname(p));
|
||||
done();
|
||||
});
|
||||
const dirnameEvent = emittedOnce(ipcMain, 'dirname');
|
||||
w.loadFile(p);
|
||||
const [, dirname] = await dirnameEvent;
|
||||
expect(dirname).to.equal(path.dirname(p));
|
||||
});
|
||||
|
||||
it('loads script tag in html', function (done) {
|
||||
it('loads script tag in html', async function () {
|
||||
after(function () {
|
||||
ipcMain.removeAllListeners('ping');
|
||||
});
|
||||
|
@ -45,14 +45,13 @@ describe('asar package', () => {
|
|||
}
|
||||
});
|
||||
const p = path.resolve(asarDir, 'script.asar', 'index.html');
|
||||
const ping = emittedOnce(ipcMain, 'ping');
|
||||
w.loadFile(p);
|
||||
ipcMain.once('ping', function (event, message) {
|
||||
const [, message] = await ping;
|
||||
expect(message).to.equal('pong');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('loads video tag in html', function (done) {
|
||||
it('loads video tag in html', async function () {
|
||||
this.timeout(60000);
|
||||
|
||||
after(function () {
|
||||
|
@ -69,14 +68,12 @@ describe('asar package', () => {
|
|||
});
|
||||
const p = path.resolve(asarDir, 'video.asar', 'index.html');
|
||||
w.loadFile(p);
|
||||
ipcMain.on('asar-video', function (event, message, error) {
|
||||
const [, message, error] = await emittedOnce(ipcMain, 'asar-video');
|
||||
if (message === 'ended') {
|
||||
expect(error).to.be.null();
|
||||
done();
|
||||
} else if (message === 'error') {
|
||||
done(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as url from 'url';
|
|||
import * as ChildProcess from 'child_process';
|
||||
import { EventEmitter } from 'events';
|
||||
import { promisify } from 'util';
|
||||
import { ifit, ifdescribe, delay } from './spec-helpers';
|
||||
import { ifit, ifdescribe, delay, defer } from './spec-helpers';
|
||||
import { AddressInfo } from 'net';
|
||||
import { PipeTransport } from './pipe-transport';
|
||||
|
||||
|
@ -257,22 +257,21 @@ describe('command line switches', () => {
|
|||
});
|
||||
describe('--lang switch', () => {
|
||||
const currentLocale = app.getLocale();
|
||||
const testLocale = (locale: string, result: string, done: () => void) => {
|
||||
const testLocale = async (locale: string, result: string) => {
|
||||
const appPath = path.join(fixturesPath, 'api', 'locale-check');
|
||||
const electronPath = process.execPath;
|
||||
let output = '';
|
||||
appProcess = ChildProcess.spawn(electronPath, [appPath, `--lang=${locale}`]);
|
||||
|
||||
let output = '';
|
||||
appProcess.stdout.on('data', (data) => { output += data; });
|
||||
appProcess.stdout.on('end', () => {
|
||||
|
||||
await emittedOnce(appProcess.stdout, 'end');
|
||||
output = output.replace(/(\r\n|\n|\r)/gm, '');
|
||||
expect(output).to.equal(result);
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
it('should set the locale', (done) => testLocale('fr', 'fr', done));
|
||||
it('should not set an invalid locale', (done) => testLocale('asdfkl', currentLocale, done));
|
||||
it('should set the locale', async () => testLocale('fr', 'fr'));
|
||||
it('should not set an invalid locale', async () => testLocale('asdfkl', currentLocale));
|
||||
});
|
||||
|
||||
describe('--remote-debugging-pipe switch', () => {
|
||||
|
@ -330,10 +329,15 @@ describe('command line switches', () => {
|
|||
appProcess!.stderr.removeAllListeners('data');
|
||||
const port = m[1];
|
||||
http.get(`http://127.0.0.1:${port}`, (res) => {
|
||||
res.destroy();
|
||||
try {
|
||||
expect(res.statusCode).to.eql(200);
|
||||
expect(parseInt(res.headers['content-length']!)).to.be.greaterThan(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
} finally {
|
||||
res.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -551,7 +555,7 @@ describe('chromium features', () => {
|
|||
|
||||
describe('window.open', () => {
|
||||
for (const show of [true, false]) {
|
||||
it(`inherits parent visibility over parent {show=${show}} option`, (done) => {
|
||||
it(`inherits parent visibility over parent {show=${show}} option`, async () => {
|
||||
const w = new BrowserWindow({ show });
|
||||
|
||||
// toggle visibility
|
||||
|
@ -561,12 +565,12 @@ describe('chromium features', () => {
|
|||
w.show();
|
||||
}
|
||||
|
||||
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
|
||||
expect(options.show).to.equal(w.isVisible());
|
||||
w.close();
|
||||
done();
|
||||
});
|
||||
defer(() => { w.close(); });
|
||||
|
||||
const newWindow = emittedOnce(w.webContents, 'new-window');
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'window-open.html'));
|
||||
const [,,,, options] = await newWindow;
|
||||
expect(options.show).to.equal(w.isVisible());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -602,7 +606,7 @@ describe('chromium features', () => {
|
|||
expect(preferences.javascript).to.be.false();
|
||||
});
|
||||
|
||||
it('handles cycles when merging the parent options into the child options', (done) => {
|
||||
it('handles cycles when merging the parent options into the child options', async () => {
|
||||
const foo = {} as any;
|
||||
foo.bar = foo;
|
||||
foo.baz = {
|
||||
|
@ -614,7 +618,7 @@ describe('chromium features', () => {
|
|||
const w = new BrowserWindow({ show: false, foo: foo } as any);
|
||||
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'window-open.html'));
|
||||
w.webContents.once('new-window', (event, url, frameName, disposition, options) => {
|
||||
const [,,,, options] = await emittedOnce(w.webContents, 'new-window');
|
||||
expect(options.show).to.be.false();
|
||||
expect((options as any).foo).to.deep.equal({
|
||||
bar: undefined,
|
||||
|
@ -629,8 +633,6 @@ describe('chromium features', () => {
|
|||
}
|
||||
}
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('defines a window.location getter', async () => {
|
||||
|
@ -959,44 +961,39 @@ describe('chromium features', () => {
|
|||
contents = null as any;
|
||||
});
|
||||
|
||||
it('cannot access localStorage', (done) => {
|
||||
ipcMain.once('local-storage-response', (event, error) => {
|
||||
expect(error).to.equal('Failed to read the \'localStorage\' property from \'Window\': Access is denied for this document.');
|
||||
done();
|
||||
});
|
||||
it('cannot access localStorage', async () => {
|
||||
const response = emittedOnce(ipcMain, 'local-storage-response');
|
||||
contents.loadURL(protocolName + '://host/localStorage');
|
||||
const [, error] = await response;
|
||||
expect(error).to.equal('Failed to read the \'localStorage\' property from \'Window\': Access is denied for this document.');
|
||||
});
|
||||
|
||||
it('cannot access sessionStorage', (done) => {
|
||||
ipcMain.once('session-storage-response', (event, error) => {
|
||||
expect(error).to.equal('Failed to read the \'sessionStorage\' property from \'Window\': Access is denied for this document.');
|
||||
done();
|
||||
});
|
||||
it('cannot access sessionStorage', async () => {
|
||||
const response = emittedOnce(ipcMain, 'session-storage-response');
|
||||
contents.loadURL(`${protocolName}://host/sessionStorage`);
|
||||
const [, error] = await response;
|
||||
expect(error).to.equal('Failed to read the \'sessionStorage\' property from \'Window\': Access is denied for this document.');
|
||||
});
|
||||
|
||||
it('cannot access WebSQL database', (done) => {
|
||||
ipcMain.once('web-sql-response', (event, error) => {
|
||||
expect(error).to.equal('Failed to execute \'openDatabase\' on \'Window\': Access to the WebDatabase API is denied in this context.');
|
||||
done();
|
||||
});
|
||||
it('cannot access WebSQL database', async () => {
|
||||
const response = emittedOnce(ipcMain, 'web-sql-response');
|
||||
contents.loadURL(`${protocolName}://host/WebSQL`);
|
||||
const [, error] = await response;
|
||||
expect(error).to.equal('Failed to execute \'openDatabase\' on \'Window\': Access to the WebDatabase API is denied in this context.');
|
||||
});
|
||||
|
||||
it('cannot access indexedDB', (done) => {
|
||||
ipcMain.once('indexed-db-response', (event, error) => {
|
||||
expect(error).to.equal('Failed to execute \'open\' on \'IDBFactory\': access to the Indexed Database API is denied in this context.');
|
||||
done();
|
||||
});
|
||||
it('cannot access indexedDB', async () => {
|
||||
const response = emittedOnce(ipcMain, 'indexed-db-response');
|
||||
contents.loadURL(`${protocolName}://host/indexedDB`);
|
||||
const [, error] = await response;
|
||||
expect(error).to.equal('Failed to execute \'open\' on \'IDBFactory\': access to the Indexed Database API is denied in this context.');
|
||||
});
|
||||
|
||||
it('cannot access cookie', (done) => {
|
||||
ipcMain.once('cookie-response', (event, error) => {
|
||||
expect(error).to.equal('Failed to set the \'cookie\' property on \'Document\': Access is denied for this document.');
|
||||
done();
|
||||
});
|
||||
it('cannot access cookie', async () => {
|
||||
const response = emittedOnce(ipcMain, 'cookie-response');
|
||||
contents.loadURL(`${protocolName}://host/cookie`);
|
||||
const [, error] = await response;
|
||||
expect(error).to.equal('Failed to set the \'cookie\' property on \'Document\': Access is denied for this document.');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1034,7 +1031,7 @@ describe('chromium features', () => {
|
|||
afterEach(closeAllWindows);
|
||||
|
||||
const testLocalStorageAfterXSiteRedirect = (testTitle: string, extraPreferences = {}) => {
|
||||
it(testTitle, (done) => {
|
||||
it(testTitle, async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
...extraPreferences
|
||||
|
@ -1047,11 +1044,8 @@ describe('chromium features', () => {
|
|||
expect(url).to.equal(`${serverCrossSiteUrl}/redirected`);
|
||||
redirected = true;
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
await w.loadURL(`${serverUrl}/redirect-cross-site`);
|
||||
expect(redirected).to.be.true('didnt redirect');
|
||||
done();
|
||||
});
|
||||
w.loadURL(`${serverUrl}/redirect-cross-site`);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1363,8 +1357,13 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
|
|||
server.close();
|
||||
});
|
||||
|
||||
it('can fullscreen from out-of-process iframes (OOPIFs)', done => {
|
||||
ipcMain.once('fullscreenChange', async () => {
|
||||
it('can fullscreen from out-of-process iframes (OOPIFs)', async () => {
|
||||
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
|
||||
const html =
|
||||
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
|
||||
w.loadURL(`data:text/html,${html}`);
|
||||
await fullscreenChange;
|
||||
|
||||
const fullscreenWidth = await w.webContents.executeJavaScript(
|
||||
"document.querySelector('iframe').offsetWidth"
|
||||
);
|
||||
|
@ -1380,17 +1379,13 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
|
|||
"document.querySelector('iframe').offsetWidth"
|
||||
);
|
||||
expect(width).to.equal(0);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
const html =
|
||||
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
|
||||
w.loadURL(`data:text/html,${html}`);
|
||||
});
|
||||
it('can fullscreen from in-process iframes', async () => {
|
||||
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'fullscreen-ipif.html'));
|
||||
await fullscreenChange;
|
||||
|
||||
it('can fullscreen from in-process iframes', done => {
|
||||
ipcMain.once('fullscreenChange', async () => {
|
||||
const fullscreenWidth = await w.webContents.executeJavaScript(
|
||||
"document.querySelector('iframe').offsetWidth"
|
||||
);
|
||||
|
@ -1401,9 +1396,5 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
|
|||
"document.querySelector('iframe').offsetWidth"
|
||||
);
|
||||
expect(width).to.equal(0);
|
||||
done();
|
||||
});
|
||||
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'fullscreen-ipif.html'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as fs from 'fs';
|
|||
import { BrowserWindow } from 'electron/main';
|
||||
import { ifdescribe, ifit } from './spec-helpers';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
import * as childProcess from 'child_process';
|
||||
|
||||
const Module = require('module');
|
||||
|
@ -23,12 +24,10 @@ describe('modules support', () => {
|
|||
await expect(w.webContents.executeJavaScript('{ require(\'echo\'); null }')).to.be.fulfilled();
|
||||
});
|
||||
|
||||
ifit(features.isRunAsNodeEnabled())('can be required in node binary', function (done) {
|
||||
ifit(features.isRunAsNodeEnabled())('can be required in node binary', async function () {
|
||||
const child = childProcess.fork(path.join(fixtures, 'module', 'echo.js'));
|
||||
child.on('message', (msg) => {
|
||||
const [msg] = await emittedOnce(child, 'message');
|
||||
expect(msg).to.equal('ok');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
ifit(process.platform === 'win32')('can be required if electron.exe is renamed', () => {
|
||||
|
|
|
@ -12,13 +12,12 @@ describe('node feature', () => {
|
|||
const fixtures = path.join(__dirname, '..', 'spec', 'fixtures');
|
||||
describe('child_process', () => {
|
||||
describe('child_process.fork', () => {
|
||||
it('Works in browser process', (done) => {
|
||||
it('Works in browser process', async () => {
|
||||
const child = childProcess.fork(path.join(fixtures, 'module', 'ping.js'));
|
||||
child.on('message', (msg) => {
|
||||
expect(msg).to.equal('message');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -199,7 +198,7 @@ describe('node feature', () => {
|
|||
child.stdout.on('data', listener);
|
||||
});
|
||||
|
||||
it('Supports starting the v8 inspector with --inspect and a provided port', (done) => {
|
||||
it('Supports starting the v8 inspector with --inspect and a provided port', async () => {
|
||||
child = childProcess.spawn(process.execPath, ['--inspect=17364', path.join(fixtures, 'module', 'run-as-node.js')], {
|
||||
env: { ELECTRON_RUN_AS_NODE: 'true' }
|
||||
});
|
||||
|
@ -214,18 +213,16 @@ describe('node feature', () => {
|
|||
|
||||
child.stderr.on('data', listener);
|
||||
child.stdout.on('data', listener);
|
||||
child.on('exit', () => {
|
||||
await emittedOnce(child, 'exit');
|
||||
cleanup();
|
||||
if (/^Debugger listening on ws:/m.test(output)) {
|
||||
expect(output.trim()).to.contain(':17364', 'should be listening on port 17364');
|
||||
done();
|
||||
} else {
|
||||
done(new Error(`Unexpected output: ${output.toString()}`));
|
||||
throw new Error(`Unexpected output: ${output.toString()}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Does not start the v8 inspector when --inspect is after a -- argument', (done) => {
|
||||
it('Does not start the v8 inspector when --inspect is after a -- argument', async () => {
|
||||
child = childProcess.spawn(process.execPath, [path.join(fixtures, 'module', 'noop.js'), '--', '--inspect']);
|
||||
exitPromise = emittedOnce(child, 'exit');
|
||||
|
||||
|
@ -233,14 +230,11 @@ describe('node feature', () => {
|
|||
const listener = (data: Buffer) => { output += data; };
|
||||
child.stderr.on('data', listener);
|
||||
child.stdout.on('data', listener);
|
||||
child.on('exit', () => {
|
||||
await emittedOnce(child, 'exit');
|
||||
if (output.trim().startsWith('Debugger listening on ws://')) {
|
||||
done(new Error('Inspector was started when it should not have been'));
|
||||
} else {
|
||||
done();
|
||||
throw new Error('Inspector was started when it should not have been');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// IPC Electron child process not supported on Windows
|
||||
ifit(process.platform !== 'win32')('does not crash when quitting with the inspector connected', function (done) {
|
||||
|
@ -289,20 +283,17 @@ describe('node feature', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('Supports js binding', (done) => {
|
||||
it('Supports js binding', async () => {
|
||||
child = childProcess.spawn(process.execPath, ['--inspect', path.join(fixtures, 'module', 'inspector-binding.js')], {
|
||||
env: { ELECTRON_RUN_AS_NODE: 'true' },
|
||||
stdio: ['ipc']
|
||||
}) as childProcess.ChildProcessWithoutNullStreams;
|
||||
exitPromise = emittedOnce(child, 'exit');
|
||||
|
||||
child.on('message', ({ cmd, debuggerEnabled, success }) => {
|
||||
if (cmd === 'assert') {
|
||||
const [{ cmd, debuggerEnabled, success }] = await emittedOnce(child, 'message');
|
||||
expect(cmd).to.equal('assert');
|
||||
expect(debuggerEnabled).to.be.true();
|
||||
expect(success).to.be.true();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -311,17 +302,15 @@ describe('node feature', () => {
|
|||
expect(result.status).to.equal(0);
|
||||
});
|
||||
|
||||
ifit(features.isRunAsNodeEnabled())('handles Promise timeouts correctly', (done) => {
|
||||
ifit(features.isRunAsNodeEnabled())('handles Promise timeouts correctly', async () => {
|
||||
const scriptPath = path.join(fixtures, 'module', 'node-promise-timer.js');
|
||||
const child = childProcess.spawn(process.execPath, [scriptPath], {
|
||||
env: { ELECTRON_RUN_AS_NODE: 'true' }
|
||||
});
|
||||
emittedOnce(child, 'exit').then(([code, signal]) => {
|
||||
const [code, signal] = await emittedOnce(child, 'exit');
|
||||
expect(code).to.equal(0);
|
||||
expect(signal).to.equal(null);
|
||||
child.kill();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('performs microtask checkpoint correctly', (done) => {
|
||||
|
|
|
@ -39,70 +39,51 @@ describe('webFrame module', function () {
|
|||
childFrameElement.remove();
|
||||
});
|
||||
|
||||
it('executeJavaScript() yields results via a promise and a sync callback', done => {
|
||||
it('executeJavaScript() yields results via a promise and a sync callback', async () => {
|
||||
let callbackResult, callbackError;
|
||||
|
||||
childFrame
|
||||
const executeJavaScript = childFrame
|
||||
.executeJavaScript('1 + 1', (result, error) => {
|
||||
callbackResult = result;
|
||||
callbackError = error;
|
||||
})
|
||||
.then(
|
||||
promiseResult => {
|
||||
expect(promiseResult).to.equal(2);
|
||||
done();
|
||||
},
|
||||
promiseError => {
|
||||
done(promiseError);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
expect(callbackResult).to.equal(2);
|
||||
expect(callbackError).to.be.undefined();
|
||||
|
||||
const promiseResult = await executeJavaScript;
|
||||
expect(promiseResult).to.equal(2);
|
||||
});
|
||||
|
||||
it('executeJavaScriptInIsolatedWorld() yields results via a promise and a sync callback', done => {
|
||||
it('executeJavaScriptInIsolatedWorld() yields results via a promise and a sync callback', async () => {
|
||||
let callbackResult, callbackError;
|
||||
|
||||
childFrame
|
||||
const executeJavaScriptInIsolatedWorld = childFrame
|
||||
.executeJavaScriptInIsolatedWorld(999, [{ code: '1 + 1' }], (result, error) => {
|
||||
callbackResult = result;
|
||||
callbackError = error;
|
||||
})
|
||||
.then(
|
||||
promiseResult => {
|
||||
expect(promiseResult).to.equal(2);
|
||||
done();
|
||||
},
|
||||
promiseError => {
|
||||
done(promiseError);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
expect(callbackResult).to.equal(2);
|
||||
expect(callbackError).to.be.undefined();
|
||||
|
||||
const promiseResult = await executeJavaScriptInIsolatedWorld;
|
||||
expect(promiseResult).to.equal(2);
|
||||
});
|
||||
|
||||
it('executeJavaScript() yields errors via a promise and a sync callback', done => {
|
||||
it('executeJavaScript() yields errors via a promise and a sync callback', async () => {
|
||||
let callbackResult, callbackError;
|
||||
|
||||
childFrame
|
||||
const executeJavaScript = childFrame
|
||||
.executeJavaScript('thisShouldProduceAnError()', (result, error) => {
|
||||
callbackResult = result;
|
||||
callbackError = error;
|
||||
})
|
||||
.then(
|
||||
promiseResult => {
|
||||
done(new Error('error is expected'));
|
||||
},
|
||||
promiseError => {
|
||||
expect(promiseError).to.be.an('error');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
expect(callbackResult).to.be.undefined();
|
||||
expect(callbackError).to.be.an('error');
|
||||
|
||||
await expect(executeJavaScript).to.eventually.be.rejected('error is expected');
|
||||
});
|
||||
|
||||
// executeJavaScriptInIsolatedWorld is failing to detect exec errors and is neither
|
||||
|
@ -113,23 +94,16 @@ describe('webFrame module', function () {
|
|||
// it('executeJavaScriptInIsolatedWorld() yields errors via a promise and a sync callback', done => {
|
||||
// let callbackResult, callbackError
|
||||
//
|
||||
// childFrame
|
||||
// const executeJavaScriptInIsolatedWorld = childFrame
|
||||
// .executeJavaScriptInIsolatedWorld(999, [{ code: 'thisShouldProduceAnError()' }], (result, error) => {
|
||||
// callbackResult = result
|
||||
// callbackError = error
|
||||
// })
|
||||
// .then(
|
||||
// promiseResult => {
|
||||
// done(new Error('error is expected'))
|
||||
// },
|
||||
// promiseError => {
|
||||
// expect(promiseError).to.be.an('error')
|
||||
// done()
|
||||
// }
|
||||
// )
|
||||
// });
|
||||
//
|
||||
// expect(callbackResult).to.be.undefined()
|
||||
// expect(callbackError).to.be.an('error')
|
||||
//
|
||||
// expect(executeJavaScriptInIsolatedWorld).to.eventually.be.rejected('error is expected');
|
||||
// })
|
||||
|
||||
it('executeJavaScript(InIsolatedWorld) can be used without a callback', async () => {
|
||||
|
|
|
@ -4,6 +4,8 @@ const fs = require('fs');
|
|||
const path = require('path');
|
||||
const temp = require('temp').track();
|
||||
const util = require('util');
|
||||
const { emittedOnce } = require('./events-helpers');
|
||||
const { ifit } = require('./spec-helpers');
|
||||
const nativeImage = require('electron').nativeImage;
|
||||
|
||||
const features = process._linkedBinding('electron_common_features');
|
||||
|
@ -99,53 +101,77 @@ describe('asar package', function () {
|
|||
it('reads a normal file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
fs.readFile(p, function (err, content) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(String(content).trim()).to.equal('file1');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads from a empty file', function (done) {
|
||||
const p = path.join(asarDir, 'empty.asar', 'file1');
|
||||
fs.readFile(p, function (err, content) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(String(content)).to.equal('');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads from a empty file with encoding', function (done) {
|
||||
const p = path.join(asarDir, 'empty.asar', 'file1');
|
||||
fs.readFile(p, 'utf8', function (err, content) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(content).to.equal('');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads a linked file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link1');
|
||||
fs.readFile(p, function (err, content) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(String(content).trim()).to.equal('file1');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads a file from linked directory', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link2', 'link2', 'file1');
|
||||
fs.readFile(p, function (err, content) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(String(content).trim()).to.equal('file1');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('throws ENOENT error when can not find file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
fs.readFile(p, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -192,9 +218,13 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
const dest = temp.path();
|
||||
fs.copyFile(p, dest, function (err) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(fs.readFileSync(p).equals(fs.readFileSync(dest))).to.be.true();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -202,9 +232,13 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'unpack.asar', 'a.txt');
|
||||
const dest = temp.path();
|
||||
fs.copyFile(p, dest, function (err) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(fs.readFileSync(p).equals(fs.readFileSync(dest))).to.be.true();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -339,80 +373,108 @@ describe('asar package', function () {
|
|||
it('returns information of root', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar');
|
||||
fs.lstat(p, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.false();
|
||||
expect(stats.isDirectory()).to.be.true();
|
||||
expect(stats.isSymbolicLink()).to.be.false();
|
||||
expect(stats.size).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns information of root with stats as bigint', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar');
|
||||
fs.lstat(p, { bigint: false }, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.false();
|
||||
expect(stats.isDirectory()).to.be.true();
|
||||
expect(stats.isSymbolicLink()).to.be.false();
|
||||
expect(stats.size).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns information of a normal file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link2', 'file1');
|
||||
fs.lstat(p, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.true();
|
||||
expect(stats.isDirectory()).to.be.false();
|
||||
expect(stats.isSymbolicLink()).to.be.false();
|
||||
expect(stats.size).to.equal(6);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns information of a normal directory', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'dir1');
|
||||
fs.lstat(p, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.false();
|
||||
expect(stats.isDirectory()).to.be.true();
|
||||
expect(stats.isSymbolicLink()).to.be.false();
|
||||
expect(stats.size).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns information of a linked file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link2', 'link1');
|
||||
fs.lstat(p, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.false();
|
||||
expect(stats.isDirectory()).to.be.false();
|
||||
expect(stats.isSymbolicLink()).to.be.true();
|
||||
expect(stats.size).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns information of a linked directory', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link2', 'link2');
|
||||
fs.lstat(p, function (err, stats) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(stats.isFile()).to.be.false();
|
||||
expect(stats.isDirectory()).to.be.false();
|
||||
expect(stats.isSymbolicLink()).to.be.true();
|
||||
expect(stats.size).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('throws ENOENT error when can not find file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'file4');
|
||||
fs.lstat(p, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -592,9 +654,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = 'a.asar';
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -602,9 +668,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('a.asar', 'file1');
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -612,9 +682,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('a.asar', 'dir1');
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -622,9 +696,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('a.asar', 'link2', 'link1');
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, 'a.asar', 'file1'));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -632,9 +710,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('a.asar', 'link2', 'link2');
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, 'a.asar', 'dir1'));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -642,9 +724,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('unpack.asar', 'a.txt');
|
||||
fs.realpath(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -652,8 +738,12 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync(asarDir);
|
||||
const p = path.join('a.asar', 'not-exist');
|
||||
fs.realpath(path.join(parent, p), err => {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -713,9 +803,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = 'a.asar';
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -723,9 +817,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('a.asar', 'file1');
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -733,9 +831,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('a.asar', 'dir1');
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -743,9 +845,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('a.asar', 'link2', 'link1');
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, 'a.asar', 'file1'));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -753,9 +859,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('a.asar', 'link2', 'link2');
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, 'a.asar', 'dir1'));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -763,9 +873,13 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('unpack.asar', 'a.txt');
|
||||
fs.realpath.native(path.join(parent, p), (err, r) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(r).to.equal(path.join(parent, p));
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -773,8 +887,12 @@ describe('asar package', function () {
|
|||
const parent = fs.realpathSync.native(asarDir);
|
||||
const p = path.join('a.asar', 'not-exist');
|
||||
fs.realpath.native(path.join(parent, p), err => {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -820,9 +938,13 @@ describe('asar package', function () {
|
|||
it('reads dirs from root', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar');
|
||||
fs.readdir(p, function (err, dirs) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(dirs).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -830,6 +952,7 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar');
|
||||
|
||||
fs.readdir(p, { withFileTypes: true }, (err, dirs) => {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
for (const dir of dirs) {
|
||||
expect(dir instanceof fs.Dirent).to.be.true();
|
||||
|
@ -838,32 +961,47 @@ describe('asar package', function () {
|
|||
const names = dirs.map(a => a.name);
|
||||
expect(names).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads dirs from a normal dir', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'dir1');
|
||||
fs.readdir(p, function (err, dirs) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(dirs).to.deep.equal(['file1', 'file2', 'file3', 'link1', 'link2']);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reads dirs from a linked dir', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'link2', 'link2');
|
||||
fs.readdir(p, function (err, dirs) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
expect(dirs).to.deep.equal(['file1', 'file2', 'file3', 'link1', 'link2']);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('throws ENOENT error when can not find file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
fs.readdir(p, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -942,8 +1080,12 @@ describe('asar package', function () {
|
|||
it('throws ENOENT error when can not find file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
fs.open(p, 'r', function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -968,8 +1110,12 @@ describe('asar package', function () {
|
|||
it('throws error when calling inside asar archive', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
fs.mkdir(p, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOTDIR');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -995,8 +1141,12 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
// eslint-disable-next-line
|
||||
fs.exists(p, function (exists) {
|
||||
try {
|
||||
expect(exists).to.be.true();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1004,8 +1154,12 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
// eslint-disable-next-line
|
||||
fs.exists(p, function (exists) {
|
||||
try {
|
||||
expect(exists).to.be.false();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1013,8 +1167,12 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
// eslint-disable-next-line
|
||||
util.promisify(fs.exists)(p).then(exists => {
|
||||
try {
|
||||
expect(exists).to.be.true();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1022,8 +1180,12 @@ describe('asar package', function () {
|
|||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
// eslint-disable-next-line
|
||||
util.promisify(fs.exists)(p).then(exists => {
|
||||
try {
|
||||
expect(exists).to.be.false();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1044,32 +1206,48 @@ describe('asar package', function () {
|
|||
it('accesses a normal file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
fs.access(p, function (err) {
|
||||
try {
|
||||
expect(err).to.be.undefined();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error when called with write mode', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'file1');
|
||||
fs.access(p, fs.constants.R_OK | fs.constants.W_OK, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('EACCES');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error when called on non-existent file', function (done) {
|
||||
const p = path.join(asarDir, 'a.asar', 'not-exist');
|
||||
fs.access(p, function (err) {
|
||||
try {
|
||||
expect(err.code).to.equal('ENOENT');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('allows write mode for unpacked files', function (done) {
|
||||
const p = path.join(asarDir, 'unpack.asar', 'a.txt');
|
||||
fs.access(p, fs.constants.R_OK | fs.constants.W_OK, function (err) {
|
||||
try {
|
||||
expect(err).to.be.null();
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1136,8 +1314,12 @@ describe('asar package', function () {
|
|||
it('opens a normal js file', function (done) {
|
||||
const child = ChildProcess.fork(path.join(asarDir, 'a.asar', 'ping.js'));
|
||||
child.on('message', function (msg) {
|
||||
try {
|
||||
expect(msg).to.equal('message');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
child.send('message');
|
||||
});
|
||||
|
@ -1146,8 +1328,12 @@ describe('asar package', function () {
|
|||
const file = path.join(asarDir, 'a.asar', 'file1');
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'asar.js'));
|
||||
child.on('message', function (content) {
|
||||
try {
|
||||
expect(content).to.equal(fs.readFileSync(file).toString());
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
child.send(file);
|
||||
});
|
||||
|
@ -1158,9 +1344,13 @@ describe('asar package', function () {
|
|||
|
||||
it('should not try to extract the command if there is a reference to a file inside an .asar', function (done) {
|
||||
ChildProcess.exec('echo ' + echo + ' foo bar', function (error, stdout) {
|
||||
try {
|
||||
expect(error).to.be.null();
|
||||
expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1175,9 +1365,13 @@ describe('asar package', function () {
|
|||
const echo = path.join(asarDir, 'echo.asar', 'echo');
|
||||
|
||||
it('should not try to extract the command if there is a reference to a file inside an .asar', function (done) {
|
||||
try {
|
||||
const stdout = ChildProcess.execSync('echo ' + echo + ' foo bar');
|
||||
expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1194,21 +1388,28 @@ describe('asar package', function () {
|
|||
|
||||
it('executes binaries', function (done) {
|
||||
execFile(echo, ['test'], function (error, stdout) {
|
||||
try {
|
||||
expect(error).to.be.null();
|
||||
expect(stdout).to.equal('test\n');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('executes binaries without callback', function (done) {
|
||||
const process = execFile(echo, ['test']);
|
||||
process.on('close', function (code) {
|
||||
try {
|
||||
expect(code).to.equal(0);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
process.on('error', function () {
|
||||
expect.fail();
|
||||
done();
|
||||
done('error');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1351,9 +1552,13 @@ describe('asar package', function () {
|
|||
}
|
||||
});
|
||||
forked.on('message', function (stats) {
|
||||
try {
|
||||
expect(stats.isFile).to.be.true();
|
||||
expect(stats.size).to.equal(778);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1370,10 +1575,14 @@ describe('asar package', function () {
|
|||
output += data;
|
||||
});
|
||||
spawned.stdout.on('close', function () {
|
||||
try {
|
||||
const stats = JSON.parse(output);
|
||||
expect(stats.isFile).to.be.true();
|
||||
expect(stats.size).to.equal(778);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1383,32 +1592,48 @@ describe('asar package', function () {
|
|||
it('can request a file in package', function (done) {
|
||||
const p = path.resolve(asarDir, 'a.asar', 'file1');
|
||||
$.get('file://' + p, function (data) {
|
||||
try {
|
||||
expect(data.trim()).to.equal('file1');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('can request a file in package with unpacked files', function (done) {
|
||||
const p = path.resolve(asarDir, 'unpack.asar', 'a.txt');
|
||||
$.get('file://' + p, function (data) {
|
||||
try {
|
||||
expect(data.trim()).to.equal('a');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('can request a linked file in package', function (done) {
|
||||
const p = path.resolve(asarDir, 'a.asar', 'link2', 'link1');
|
||||
$.get('file://' + p, function (data) {
|
||||
try {
|
||||
expect(data.trim()).to.equal('file1');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('can request a file in filesystem', function (done) {
|
||||
const p = path.resolve(asarDir, 'file');
|
||||
$.get('file://' + p, function (data) {
|
||||
try {
|
||||
expect(data.trim()).to.equal('file');
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1417,8 +1642,12 @@ describe('asar package', function () {
|
|||
$.ajax({
|
||||
url: 'file://' + p,
|
||||
error: function (err) {
|
||||
try {
|
||||
expect(err.status).to.equal(404);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1433,18 +1662,12 @@ describe('asar package', function () {
|
|||
expect(stats.isFile()).to.be.true();
|
||||
});
|
||||
|
||||
it('is available in forked scripts', function (done) {
|
||||
if (!features.isRunAsNodeEnabled()) {
|
||||
this.skip();
|
||||
done();
|
||||
}
|
||||
|
||||
ifit(features.isRunAsNodeEnabled())('is available in forked scripts', async function () {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'original-fs.js'));
|
||||
child.on('message', function (msg) {
|
||||
expect(msg).to.equal('object');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('object');
|
||||
});
|
||||
|
||||
it('can be used with streams', () => {
|
||||
|
|
|
@ -6,8 +6,9 @@ const ws = require('ws');
|
|||
const url = require('url');
|
||||
const ChildProcess = require('child_process');
|
||||
const { ipcRenderer } = require('electron');
|
||||
const { emittedOnce } = require('./events-helpers');
|
||||
const { emittedOnce, waitForEvent } = require('./events-helpers');
|
||||
const { resolveGetters } = require('./expect-helpers');
|
||||
const { ifdescribe, delay } = require('./spec-helpers');
|
||||
const features = process._linkedBinding('electron_common_features');
|
||||
|
||||
/* Most of the APIs here don't use standard callbacks */
|
||||
|
@ -15,14 +16,6 @@ const features = process._linkedBinding('electron_common_features');
|
|||
|
||||
describe('chromium feature', () => {
|
||||
const fixtures = path.resolve(__dirname, 'fixtures');
|
||||
let listener = null;
|
||||
|
||||
afterEach(() => {
|
||||
if (listener != null) {
|
||||
window.removeEventListener('message', listener);
|
||||
}
|
||||
listener = null;
|
||||
});
|
||||
|
||||
describe('heap snapshot', () => {
|
||||
it('does not crash', function () {
|
||||
|
@ -46,58 +39,34 @@ describe('chromium feature', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('navigator.geolocation', () => {
|
||||
before(function () {
|
||||
if (!features.isFakeLocationProviderEnabled()) {
|
||||
return this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns position when permission is granted', (done) => {
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
ifdescribe(features.isFakeLocationProviderEnabled())('navigator.geolocation', () => {
|
||||
it('returns position when permission is granted', async () => {
|
||||
const position = await new Promise((resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject));
|
||||
expect(position).to.have.a.property('coords');
|
||||
expect(position).to.have.a.property('timestamp');
|
||||
done();
|
||||
}, (error) => {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('window.open', () => {
|
||||
it('accepts "nodeIntegration" as feature', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
expect(event.data.isProcessGlobalUndefined).to.be.true();
|
||||
it('accepts "nodeIntegration" as feature', async () => {
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(`file://${fixtures}/pages/window-opener-node.html`, '', 'nodeIntegration=no,show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(`file://${fixtures}/pages/window-opener-node.html`, '', 'nodeIntegration=no,show=no');
|
||||
expect(event.data.isProcessGlobalUndefined).to.be.true();
|
||||
});
|
||||
|
||||
it('inherit options of parent window', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
it('inherit options of parent window', async () => {
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
const width = outerWidth;
|
||||
const height = outerHeight;
|
||||
expect(event.data).to.equal(`size: ${width} ${height}`);
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no');
|
||||
});
|
||||
|
||||
it('disables node integration when it is disabled on the parent window', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
expect(event.data.isProcessGlobalUndefined).to.be.true();
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
|
||||
it('disables node integration when it is disabled on the parent window', async () => {
|
||||
const windowUrl = require('url').format({
|
||||
pathname: `${fixtures}/pages/window-opener-no-node-integration.html`,
|
||||
protocol: 'file',
|
||||
|
@ -106,18 +75,14 @@ describe('chromium feature', () => {
|
|||
},
|
||||
slashes: true
|
||||
});
|
||||
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no');
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(windowUrl, '', 'nodeIntegration=no,show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
expect(event.data.isProcessGlobalUndefined).to.be.true();
|
||||
});
|
||||
|
||||
it('disables the <webview> tag when it is disabled on the parent window', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
expect(event.data.isWebViewGlobalUndefined).to.be.true();
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
|
||||
it('disables the <webview> tag when it is disabled on the parent window', async () => {
|
||||
const windowUrl = require('url').format({
|
||||
pathname: `${fixtures}/pages/window-opener-no-webview-tag.html`,
|
||||
protocol: 'file',
|
||||
|
@ -126,22 +91,23 @@ describe('chromium feature', () => {
|
|||
},
|
||||
slashes: true
|
||||
});
|
||||
b = window.open(windowUrl, '', 'webviewTag=no,nodeIntegration=yes,show=no');
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(windowUrl, '', 'webviewTag=no,nodeIntegration=yes,show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
expect(event.data.isWebViewGlobalUndefined).to.be.true();
|
||||
});
|
||||
|
||||
it('does not override child options', (done) => {
|
||||
let b = null;
|
||||
it('does not override child options', async () => {
|
||||
const size = {
|
||||
width: 350,
|
||||
height: 450
|
||||
};
|
||||
listener = (event) => {
|
||||
expect(event.data).to.equal(`size: ${size.width} ${size.height}`);
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no,width=' + size.width + ',height=' + size.height);
|
||||
const event = await message;
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no,width=' + size.width + ',height=' + size.height);
|
||||
expect(event.data).to.equal(`size: ${size.width} ${size.height}`);
|
||||
});
|
||||
|
||||
it('throws an exception when the arguments cannot be converted to strings', () => {
|
||||
|
@ -164,15 +130,12 @@ describe('chromium feature', () => {
|
|||
});
|
||||
|
||||
describe('window.opener', () => {
|
||||
it('is not null for window opened by window.open', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
expect(event.data).to.equal('object');
|
||||
it('is not null for window opened by window.open', async () => {
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(`file://${fixtures}/pages/window-opener.html`, '', 'show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(`file://${fixtures}/pages/window-opener.html`, '', 'show=no');
|
||||
expect(event.data).to.equal('object');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -187,26 +150,21 @@ describe('chromium feature', () => {
|
|||
});
|
||||
|
||||
describe('window.opener.postMessage', () => {
|
||||
it('sets source and origin correctly', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
window.removeEventListener('message', listener);
|
||||
it('sets source and origin correctly', async () => {
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(`file://${fixtures}/pages/window-opener-postMessage.html`, '', 'show=no');
|
||||
const event = await message;
|
||||
try {
|
||||
expect(event.source).to.deep.equal(b);
|
||||
b.close();
|
||||
expect(event.origin).to.equal('file://');
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(`file://${fixtures}/pages/window-opener-postMessage.html`, '', 'show=no');
|
||||
} finally {
|
||||
b.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('supports windows opened from a <webview>', (done) => {
|
||||
it('supports windows opened from a <webview>', async () => {
|
||||
const webview = new WebView();
|
||||
webview.addEventListener('console-message', (e) => {
|
||||
webview.remove();
|
||||
expect(e.message).to.equal('message');
|
||||
done();
|
||||
});
|
||||
const consoleMessage = waitForEvent(webview, 'console-message');
|
||||
webview.allowpopups = true;
|
||||
webview.src = url.format({
|
||||
pathname: `${fixtures}/pages/webview-opener-postMessage.html`,
|
||||
|
@ -217,6 +175,9 @@ describe('chromium feature', () => {
|
|||
slashes: true
|
||||
});
|
||||
document.body.appendChild(webview);
|
||||
const event = await consoleMessage;
|
||||
webview.remove();
|
||||
expect(event.message).to.equal('message');
|
||||
});
|
||||
|
||||
describe('targetOrigin argument', () => {
|
||||
|
@ -239,16 +200,12 @@ describe('chromium feature', () => {
|
|||
server.close();
|
||||
});
|
||||
|
||||
it('delivers messages that match the origin', (done) => {
|
||||
let b = null;
|
||||
listener = (event) => {
|
||||
window.removeEventListener('message', listener);
|
||||
it('delivers messages that match the origin', async () => {
|
||||
const message = waitForEvent(window, 'message');
|
||||
const b = window.open(serverURL, '', 'show=no');
|
||||
const event = await message;
|
||||
b.close();
|
||||
expect(event.data).to.equal('deliver');
|
||||
done();
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
b = window.open(serverURL, '', 'show=no');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -273,71 +230,63 @@ describe('chromium feature', () => {
|
|||
});
|
||||
|
||||
describe('web workers', () => {
|
||||
it('Worker can work', (done) => {
|
||||
it('Worker can work', async () => {
|
||||
const worker = new Worker('../fixtures/workers/worker.js');
|
||||
const message = 'ping';
|
||||
worker.onmessage = (event) => {
|
||||
expect(event.data).to.equal(message);
|
||||
worker.terminate();
|
||||
done();
|
||||
};
|
||||
const eventPromise = new Promise((resolve) => { worker.onmessage = resolve; });
|
||||
worker.postMessage(message);
|
||||
});
|
||||
|
||||
it('Worker has no node integration by default', (done) => {
|
||||
const worker = new Worker('../fixtures/workers/worker_node.js');
|
||||
worker.onmessage = (event) => {
|
||||
expect(event.data).to.equal('undefined undefined undefined undefined');
|
||||
const event = await eventPromise;
|
||||
worker.terminate();
|
||||
done();
|
||||
};
|
||||
expect(event.data).to.equal(message);
|
||||
});
|
||||
|
||||
it('Worker has node integration with nodeIntegrationInWorker', (done) => {
|
||||
const webview = new WebView();
|
||||
webview.addEventListener('ipc-message', (e) => {
|
||||
expect(e.channel).to.equal('object function object function');
|
||||
webview.remove();
|
||||
done();
|
||||
it('Worker has no node integration by default', async () => {
|
||||
const worker = new Worker('../fixtures/workers/worker_node.js');
|
||||
const event = await new Promise((resolve) => { worker.onmessage = resolve; });
|
||||
worker.terminate();
|
||||
expect(event.data).to.equal('undefined undefined undefined undefined');
|
||||
});
|
||||
|
||||
it('Worker has node integration with nodeIntegrationInWorker', async () => {
|
||||
const webview = new WebView();
|
||||
const eventPromise = waitForEvent(webview, 'ipc-message');
|
||||
webview.src = `file://${fixtures}/pages/worker.html`;
|
||||
webview.setAttribute('webpreferences', 'nodeIntegration, nodeIntegrationInWorker');
|
||||
document.body.appendChild(webview);
|
||||
const event = await eventPromise;
|
||||
webview.remove();
|
||||
expect(event.channel).to.equal('object function object function');
|
||||
});
|
||||
|
||||
describe('SharedWorker', () => {
|
||||
it('can work', async () => {
|
||||
const worker = new SharedWorker('../fixtures/workers/shared_worker.js');
|
||||
const message = 'ping';
|
||||
const eventPromise = new Promise((resolve) => { worker.port.onmessage = resolve; });
|
||||
worker.port.postMessage(message);
|
||||
const event = await eventPromise;
|
||||
expect(event.data).to.equal(message);
|
||||
});
|
||||
|
||||
it('has no node integration by default', async () => {
|
||||
const worker = new SharedWorker('../fixtures/workers/shared_worker_node.js');
|
||||
const event = await new Promise((resolve) => { worker.port.onmessage = resolve; });
|
||||
expect(event.data).to.equal('undefined undefined undefined undefined');
|
||||
});
|
||||
|
||||
// FIXME: disabled during chromium update due to crash in content::WorkerScriptFetchInitiator::CreateScriptLoaderOnIO
|
||||
xdescribe('SharedWorker', () => {
|
||||
it('can work', (done) => {
|
||||
const worker = new SharedWorker('../fixtures/workers/shared_worker.js');
|
||||
const message = 'ping';
|
||||
worker.port.onmessage = (event) => {
|
||||
expect(event.data).to.equal(message);
|
||||
done();
|
||||
};
|
||||
worker.port.postMessage(message);
|
||||
});
|
||||
|
||||
it('has no node integration by default', (done) => {
|
||||
const worker = new SharedWorker('../fixtures/workers/shared_worker_node.js');
|
||||
worker.port.onmessage = (event) => {
|
||||
expect(event.data).to.equal('undefined undefined undefined undefined');
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it('has node integration with nodeIntegrationInWorker', (done) => {
|
||||
xit('has node integration with nodeIntegrationInWorker', async () => {
|
||||
const webview = new WebView();
|
||||
webview.addEventListener('console-message', (e) => {
|
||||
console.log(e);
|
||||
});
|
||||
webview.addEventListener('ipc-message', (e) => {
|
||||
expect(e.channel).to.equal('object function object function');
|
||||
webview.remove();
|
||||
done();
|
||||
});
|
||||
const eventPromise = waitForEvent(webview, 'ipc-message');
|
||||
webview.src = `file://${fixtures}/pages/shared_worker.html`;
|
||||
webview.setAttribute('webpreferences', 'nodeIntegration, nodeIntegrationInWorker');
|
||||
document.body.appendChild(webview);
|
||||
const event = await eventPromise;
|
||||
webview.remove();
|
||||
expect(event.channel).to.equal('object function object function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -353,13 +302,11 @@ describe('chromium feature', () => {
|
|||
document.body.removeChild(iframe);
|
||||
});
|
||||
|
||||
it('does not have node integration', (done) => {
|
||||
it('does not have node integration', async () => {
|
||||
iframe.src = `file://${fixtures}/pages/set-global.html`;
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = () => {
|
||||
await waitForEvent(iframe, 'load');
|
||||
expect(iframe.contentWindow.test).to.equal('undefined undefined undefined');
|
||||
done();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -367,7 +314,7 @@ describe('chromium feature', () => {
|
|||
describe('DOM storage quota increase', () => {
|
||||
['localStorage', 'sessionStorage'].forEach((storageName) => {
|
||||
const storage = window[storageName];
|
||||
it(`allows saving at least 40MiB in ${storageName}`, (done) => {
|
||||
it(`allows saving at least 40MiB in ${storageName}`, async () => {
|
||||
// Although JavaScript strings use UTF-16, the underlying
|
||||
// storage provider may encode strings differently, muddling the
|
||||
// translation between character and byte counts. However,
|
||||
|
@ -384,11 +331,12 @@ describe('chromium feature', () => {
|
|||
// failed to detect a real problem (perhaps related to DOM storage data caching)
|
||||
// wherein calling `getItem` immediately after `setItem` would appear to work
|
||||
// but then later (e.g. next tick) it would not.
|
||||
setTimeout(() => {
|
||||
await delay(1);
|
||||
try {
|
||||
expect(storage.getItem(testKeyName)).to.have.lengthOf(length);
|
||||
} finally {
|
||||
storage.removeItem(testKeyName);
|
||||
done();
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
it(`throws when attempting to use more than 128MiB in ${storageName}`, () => {
|
||||
expect(() => {
|
||||
|
@ -404,11 +352,11 @@ describe('chromium feature', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('requesting persitent quota works', (done) => {
|
||||
navigator.webkitPersistentStorage.requestQuota(1024 * 1024, (grantedBytes) => {
|
||||
expect(grantedBytes).to.equal(1048576);
|
||||
done();
|
||||
it('requesting persitent quota works', async () => {
|
||||
const grantedBytes = await new Promise(resolve => {
|
||||
navigator.webkitPersistentStorage.requestQuota(1024 * 1024, resolve);
|
||||
});
|
||||
expect(grantedBytes).to.equal(1048576);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -20,96 +20,85 @@ describe('node feature', () => {
|
|||
});
|
||||
|
||||
describe('child_process.fork', () => {
|
||||
it('works in current process', (done) => {
|
||||
it('works in current process', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'ping.js'));
|
||||
child.on('message', msg => {
|
||||
expect(msg).to.equal('message');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('message');
|
||||
});
|
||||
|
||||
it('preserves args', (done) => {
|
||||
it('preserves args', async () => {
|
||||
const args = ['--expose_gc', '-test', '1'];
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'process_args.js'), args);
|
||||
child.on('message', (msg) => {
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(args).to.deep.equal(msg.slice(2));
|
||||
done();
|
||||
});
|
||||
child.send('message');
|
||||
});
|
||||
|
||||
it('works in forked process', (done) => {
|
||||
it('works in forked process', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'));
|
||||
child.on('message', (msg) => {
|
||||
expect(msg).to.equal('message');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('message');
|
||||
});
|
||||
|
||||
it('works in forked process when options.env is specifed', (done) => {
|
||||
it('works in forked process when options.env is specifed', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], {
|
||||
path: process.env.PATH
|
||||
});
|
||||
child.on('message', (msg) => {
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('message');
|
||||
done();
|
||||
});
|
||||
child.send('message');
|
||||
});
|
||||
|
||||
it('has String::localeCompare working in script', (done) => {
|
||||
it('has String::localeCompare working in script', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'locale-compare.js'));
|
||||
child.on('message', (msg) => {
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.deep.equal([0, -1, 1]);
|
||||
done();
|
||||
});
|
||||
child.send('message');
|
||||
});
|
||||
|
||||
it('has setImmediate working in script', (done) => {
|
||||
it('has setImmediate working in script', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'set-immediate.js'));
|
||||
child.on('message', (msg) => {
|
||||
expect(msg).to.equal('ok');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(child, 'message');
|
||||
child.send('message');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('ok');
|
||||
});
|
||||
|
||||
it('pipes stdio', (done) => {
|
||||
it('pipes stdio', async () => {
|
||||
const child = ChildProcess.fork(path.join(fixtures, 'module', 'process-stdout.js'), { silent: true });
|
||||
let data = '';
|
||||
child.stdout.on('data', (chunk) => {
|
||||
data += String(chunk);
|
||||
});
|
||||
child.on('close', (code) => {
|
||||
const [code] = await emittedOnce(child, 'close');
|
||||
expect(code).to.equal(0);
|
||||
expect(data).to.equal('pipes stdio');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('works when sending a message to a process forked with the --eval argument', (done) => {
|
||||
it('works when sending a message to a process forked with the --eval argument', async () => {
|
||||
const source = "process.on('message', (message) => { process.send(message) })";
|
||||
const forked = ChildProcess.fork('--eval', [source]);
|
||||
forked.once('message', (message) => {
|
||||
expect(message).to.equal('hello');
|
||||
done();
|
||||
});
|
||||
const message = emittedOnce(forked, 'message');
|
||||
forked.send('hello');
|
||||
const [msg] = await message;
|
||||
expect(msg).to.equal('hello');
|
||||
});
|
||||
|
||||
it('has the electron version in process.versions', (done) => {
|
||||
it('has the electron version in process.versions', async () => {
|
||||
const source = 'process.send(process.versions)';
|
||||
const forked = ChildProcess.fork('--eval', [source]);
|
||||
forked.on('message', (message) => {
|
||||
const [message] = await emittedOnce(forked, 'message');
|
||||
expect(message)
|
||||
.to.have.own.property('electron')
|
||||
.that.is.a('string')
|
||||
.and.matches(/^\d+\.\d+\.\d+(\S*)?$/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -120,7 +109,7 @@ describe('node feature', () => {
|
|||
if (child != null) child.kill();
|
||||
});
|
||||
|
||||
it('supports spawning Electron as a node process via the ELECTRON_RUN_AS_NODE env var', (done) => {
|
||||
it('supports spawning Electron as a node process via the ELECTRON_RUN_AS_NODE env var', async () => {
|
||||
child = ChildProcess.spawn(process.execPath, [path.join(__dirname, 'fixtures', 'module', 'run-as-node.js')], {
|
||||
env: {
|
||||
ELECTRON_RUN_AS_NODE: true
|
||||
|
@ -131,14 +120,12 @@ describe('node feature', () => {
|
|||
child.stdout.on('data', data => {
|
||||
output += data;
|
||||
});
|
||||
child.stdout.on('close', () => {
|
||||
await emittedOnce(child.stdout, 'close');
|
||||
expect(JSON.parse(output)).to.deep.equal({
|
||||
processLog: process.platform === 'win32' ? 'function' : 'undefined',
|
||||
processType: 'undefined',
|
||||
window: 'undefined'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -258,18 +245,15 @@ describe('node feature', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('emit error when connect to a socket path without listeners', (done) => {
|
||||
it('emit error when connect to a socket path without listeners', async () => {
|
||||
const socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock');
|
||||
const script = path.join(fixtures, 'module', 'create_socket.js');
|
||||
const child = ChildProcess.fork(script, [socketPath]);
|
||||
child.on('exit', (code) => {
|
||||
const [code] = await emittedOnce(child, 'exit');
|
||||
expect(code).to.equal(0);
|
||||
const client = require('net').connect(socketPath);
|
||||
client.on('error', (error) => {
|
||||
const [error] = await emittedOnce(client, 'error');
|
||||
expect(error.code).to.equal('ECONNREFUSED');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
exports.ifit = (condition) => (condition ? it : it.skip);
|
||||
exports.ifdescribe = (condition) => (condition ? describe : describe.skip);
|
||||
|
||||
exports.delay = (time = 0) => new Promise(resolve => setTimeout(resolve, time));
|
||||
|
|
|
@ -4,7 +4,7 @@ const http = require('http');
|
|||
const url = require('url');
|
||||
const { ipcRenderer } = require('electron');
|
||||
const { emittedOnce, waitForEvent } = require('./events-helpers');
|
||||
const { ifdescribe, ifit } = require('./spec-helpers');
|
||||
const { ifdescribe, ifit, delay } = require('./spec-helpers');
|
||||
|
||||
const features = process._linkedBinding('electron_common_features');
|
||||
const nativeModulesEnabled = process.env.ELECTRON_SKIP_NATIVE_MODULE_TESTS;
|
||||
|
@ -284,10 +284,15 @@ describe('<webview> tag', function () {
|
|||
it('sets the referrer url', (done) => {
|
||||
const referrer = 'http://github.com/';
|
||||
const server = http.createServer((req, res) => {
|
||||
res.end();
|
||||
server.close();
|
||||
try {
|
||||
expect(req.headers.referer).to.equal(referrer);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
} finally {
|
||||
res.end();
|
||||
server.close();
|
||||
}
|
||||
}).listen(0, '127.0.0.1', () => {
|
||||
const port = server.address().port;
|
||||
loadWebView(webview, {
|
||||
|
@ -737,6 +742,7 @@ describe('<webview> tag', function () {
|
|||
};
|
||||
|
||||
const loadListener = () => {
|
||||
try {
|
||||
if (loadCount === 1) {
|
||||
webview.src = `file://${fixtures}/pages/base-page.html`;
|
||||
} else if (loadCount === 2) {
|
||||
|
@ -755,6 +761,9 @@ describe('<webview> tag', function () {
|
|||
}
|
||||
|
||||
loadCount += 1;
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
};
|
||||
|
||||
webview.addEventListener('ipc-message', listener);
|
||||
|
@ -803,8 +812,12 @@ describe('<webview> tag', function () {
|
|||
server.listen(0, '127.0.0.1', () => {
|
||||
const port = server.address().port;
|
||||
webview.addEventListener('ipc-message', (e) => {
|
||||
try {
|
||||
expect(e.channel).to.equal(message);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
loadWebView(webview, {
|
||||
nodeintegration: 'on',
|
||||
|
@ -1042,15 +1055,14 @@ describe('<webview> tag', function () {
|
|||
});
|
||||
|
||||
describe('will-attach-webview event', () => {
|
||||
it('does not emit when src is not changed', (done) => {
|
||||
it('does not emit when src is not changed', async () => {
|
||||
console.log('loadWebView(webview)');
|
||||
loadWebView(webview);
|
||||
setTimeout(() => {
|
||||
await delay();
|
||||
const expectedErrorMessage =
|
||||
'The WebView must be attached to the DOM ' +
|
||||
'and the dom-ready event emitted before this method can be called.';
|
||||
expect(() => { webview.stop(); }).to.throw(expectedErrorMessage);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('supports changing the web preferences', async () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue