Update electron to 16.0.4
This commit is contained in:
parent
ba043c422b
commit
bbc13d058e
|
@ -31,7 +31,7 @@ jobs:
|
||||||
- name: Setup node.js
|
- name: Setup node.js
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16.5.0'
|
node-version: '16.9.1'
|
||||||
- name: Install global dependencies
|
- name: Install global dependencies
|
||||||
run: npm install -g yarn@1.22.10 typescript@4.4.2 ts-node@10.2.1
|
run: npm install -g yarn@1.22.10 typescript@4.4.2 ts-node@10.2.1
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16.5.0'
|
node-version: '16.9.1'
|
||||||
- run: npm install -g yarn@1.22.10
|
- run: npm install -g yarn@1.22.10
|
||||||
|
|
||||||
- name: Cache Desktop node_modules
|
- name: Cache Desktop node_modules
|
||||||
|
@ -43,7 +43,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16.5.0'
|
node-version: '16.9.1'
|
||||||
- run: npm install -g yarn@1.22.10
|
- run: npm install -g yarn@1.22.10
|
||||||
|
|
||||||
- name: Cache Desktop node_modules
|
- name: Cache Desktop node_modules
|
||||||
|
@ -63,7 +63,7 @@ jobs:
|
||||||
run: yarn electron:install-app-deps
|
run: yarn electron:install-app-deps
|
||||||
- run: yarn test-node
|
- run: yarn test-node
|
||||||
- run: yarn test-electron
|
- run: yarn test-electron
|
||||||
- run: yarn grunt test-release:osx
|
- run: yarn test-release
|
||||||
env:
|
env:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16.5.0'
|
node-version: '16.9.1'
|
||||||
- run: sudo apt-get install xvfb
|
- run: sudo apt-get install xvfb
|
||||||
- run: npm install -g yarn@1.22.10
|
- run: npm install -g yarn@1.22.10
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
LANG: en_US
|
LANG: en_US
|
||||||
LANGUAGE: en_US
|
LANGUAGE: en_US
|
||||||
- run: xvfb-run --auto-servernum yarn grunt test-release:linux
|
- run: xvfb-run --auto-servernum yarn test-release
|
||||||
env:
|
env:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16.5.0'
|
node-version: '16.9.1'
|
||||||
- run: npm install -g yarn@1.22.10
|
- run: npm install -g yarn@1.22.10
|
||||||
|
|
||||||
- name: Cache Desktop node_modules
|
- name: Cache Desktop node_modules
|
||||||
|
@ -135,7 +135,7 @@ jobs:
|
||||||
- run: type temp.json | findstr /v certificateSubjectName | findstr /v certificateSha1 > package.json
|
- run: type temp.json | findstr /v certificateSubjectName | findstr /v certificateSha1 > package.json
|
||||||
- run: yarn prepare-beta-build
|
- run: yarn prepare-beta-build
|
||||||
- run: yarn build
|
- run: yarn build
|
||||||
- run: node build\grunt.js test
|
- run: yarn test-electron
|
||||||
- run: node build\grunt.js test-release:win
|
- run: yarn test-release
|
||||||
env:
|
env:
|
||||||
SIGNAL_ENV: production
|
SIGNAL_ENV: production
|
||||||
|
|
|
@ -21,9 +21,7 @@ tsconfig.tsbuildinfo
|
||||||
js/components.js
|
js/components.js
|
||||||
js/util_worker.js
|
js/util_worker.js
|
||||||
libtextsecure/components.js
|
libtextsecure/components.js
|
||||||
libtextsecure/test/test.js
|
|
||||||
stylesheets/*.css
|
stylesheets/*.css
|
||||||
test/test.js
|
|
||||||
/storybook-static/
|
/storybook-static/
|
||||||
preload.bundle.*
|
preload.bundle.*
|
||||||
ts/sql/mainWorker.bundle.js.LICENSE.txt
|
ts/sql/mainWorker.bundle.js.LICENSE.txt
|
||||||
|
|
|
@ -281,7 +281,7 @@ yarn generate
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, run the tests using `grunt test-release:osx --dir=release`, replacing `osx` with `linux` or `win` depending on your platform.
|
Then, run the tests using `yarn test-release`.
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
|
|
||||||
|
|
283
Gruntfile.js
283
Gruntfile.js
|
@ -1,36 +1,14 @@
|
||||||
// Copyright 2014-2021 Signal Messenger, LLC
|
// Copyright 2014-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
const { join } = require('path');
|
|
||||||
const importOnce = require('node-sass-import-once');
|
const importOnce = require('node-sass-import-once');
|
||||||
const rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
const mkdirp = require('mkdirp');
|
const mkdirp = require('mkdirp');
|
||||||
const spectron = require('spectron');
|
|
||||||
const asar = require('asar');
|
|
||||||
const fs = require('fs');
|
|
||||||
const os = require('os');
|
|
||||||
const assert = require('assert');
|
|
||||||
const sass = require('node-sass');
|
const sass = require('node-sass');
|
||||||
const packageJson = require('./package.json');
|
|
||||||
|
|
||||||
/* eslint-disable more/no-then, no-console */
|
/* eslint-disable more/no-then, no-console */
|
||||||
|
|
||||||
module.exports = grunt => {
|
module.exports = grunt => {
|
||||||
async function promiseToAsyncGruntTask(promise, gruntDone) {
|
|
||||||
let succeeded = false;
|
|
||||||
try {
|
|
||||||
await promise;
|
|
||||||
succeeded = true;
|
|
||||||
} catch (err) {
|
|
||||||
grunt.log.error(err);
|
|
||||||
}
|
|
||||||
if (succeeded) {
|
|
||||||
gruntDone();
|
|
||||||
} else {
|
|
||||||
gruntDone(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bower = grunt.file.readJSON('bower.json');
|
const bower = grunt.file.readJSON('bower.json');
|
||||||
const components = [];
|
const components = [];
|
||||||
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
||||||
|
@ -47,23 +25,6 @@ module.exports = grunt => {
|
||||||
src: components,
|
src: components,
|
||||||
dest: 'js/components.js',
|
dest: 'js/components.js',
|
||||||
},
|
},
|
||||||
test: {
|
|
||||||
src: [
|
|
||||||
'node_modules/mocha/mocha.js',
|
|
||||||
'node_modules/chai/chai.js',
|
|
||||||
'test/_test.js',
|
|
||||||
],
|
|
||||||
dest: 'test/test.js',
|
|
||||||
},
|
|
||||||
libtextsecuretest: {
|
|
||||||
src: [
|
|
||||||
'node_modules/jquery/dist/jquery.js',
|
|
||||||
'node_modules/mocha/mocha.js',
|
|
||||||
'node_modules/chai/chai.js',
|
|
||||||
'libtextsecure/test/_test.js',
|
|
||||||
],
|
|
||||||
dest: 'libtextsecure/test/test.js',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
sass: {
|
sass: {
|
||||||
options: {
|
options: {
|
||||||
|
@ -116,24 +77,6 @@ module.exports = grunt => {
|
||||||
cmd: 'yarn build-protobuf',
|
cmd: 'yarn build-protobuf',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'test-release': {
|
|
||||||
osx: {
|
|
||||||
archive: `mac/${packageJson.productName}.app/Contents/Resources/app.asar`,
|
|
||||||
exe: `mac/${packageJson.productName}.app/Contents/MacOS/${packageJson.productName}`,
|
|
||||||
},
|
|
||||||
mas: {
|
|
||||||
archive: 'mas/Signal.app/Contents/Resources/app.asar',
|
|
||||||
exe: `mas/${packageJson.productName}.app/Contents/MacOS/${packageJson.productName}`,
|
|
||||||
},
|
|
||||||
linux: {
|
|
||||||
archive: 'linux-unpacked/resources/app.asar',
|
|
||||||
exe: `linux-unpacked/${packageJson.name}`,
|
|
||||||
},
|
|
||||||
win: {
|
|
||||||
archive: 'win-unpacked/resources/app.asar',
|
|
||||||
exe: `win-unpacked/${packageJson.productName}.exe`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
gitinfo: {}, // to be populated by grunt gitinfo
|
gitinfo: {}, // to be populated by grunt gitinfo
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -187,238 +130,12 @@ module.exports = grunt => {
|
||||||
mkdirp.sync('release');
|
mkdirp.sync('release');
|
||||||
});
|
});
|
||||||
|
|
||||||
async function runTests(environment) {
|
|
||||||
const { Application } = spectron;
|
|
||||||
const electronBinary =
|
|
||||||
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
|
||||||
|
|
||||||
const path = join(__dirname, 'node_modules', '.bin', electronBinary);
|
|
||||||
const args = [join(__dirname, 'app', 'main.js')];
|
|
||||||
grunt.log.writeln('Starting path', path, 'with args', args);
|
|
||||||
const app = new Application({
|
|
||||||
path,
|
|
||||||
args,
|
|
||||||
env: {
|
|
||||||
NODE_ENV: environment,
|
|
||||||
},
|
|
||||||
requireName: 'unused',
|
|
||||||
startTimeout: 30000,
|
|
||||||
});
|
|
||||||
|
|
||||||
function getMochaResults() {
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
return window.mochaResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function logForFailure() {
|
|
||||||
const temporaryDirectory = join(
|
|
||||||
os.tmpdir(),
|
|
||||||
`Signal-Desktop-tests--${Date.now()}-${Math.random()
|
|
||||||
.toString()
|
|
||||||
.slice(2)}`
|
|
||||||
);
|
|
||||||
const renderProcessLogPath = join(
|
|
||||||
temporaryDirectory,
|
|
||||||
'render-process.log'
|
|
||||||
);
|
|
||||||
const mainProcessLogPath = join(temporaryDirectory, 'main-process.log');
|
|
||||||
|
|
||||||
await fs.promises.mkdir(temporaryDirectory, { recursive: true });
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
(async () => {
|
|
||||||
const logs = await app.client.getRenderProcessLogs();
|
|
||||||
await fs.promises.writeFile(
|
|
||||||
renderProcessLogPath,
|
|
||||||
logs.map(log => JSON.stringify(log)).join('\n')
|
|
||||||
);
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
const logs = await app.client.getMainProcessLogs();
|
|
||||||
await fs.promises.writeFile(mainProcessLogPath, logs.join('\n'));
|
|
||||||
})(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
console.error();
|
|
||||||
grunt.log.error(
|
|
||||||
`Renderer process logs written to ${renderProcessLogPath}`
|
|
||||||
);
|
|
||||||
grunt.log.error(`Renderer process logs written to ${mainProcessLogPath}`);
|
|
||||||
grunt.log.error(
|
|
||||||
`For easier debugging, try NODE_ENV='${environment}' yarn start`
|
|
||||||
);
|
|
||||||
console.error();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await app.start();
|
|
||||||
|
|
||||||
grunt.log.writeln('App started. Now waiting for test results...');
|
|
||||||
await app.client.waitUntil(
|
|
||||||
() =>
|
|
||||||
app.client.execute(getMochaResults).then(data => Boolean(data.value)),
|
|
||||||
25000,
|
|
||||||
'Expected to find window.mochaResults set!'
|
|
||||||
);
|
|
||||||
|
|
||||||
const results = (await app.client.execute(getMochaResults)).value;
|
|
||||||
if (!results) {
|
|
||||||
await logForFailure();
|
|
||||||
throw new Error("Couldn't extract test results");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.failures > 0) {
|
|
||||||
const errorMessage = `Found ${results.failures} failing test${
|
|
||||||
results.failures === 1 ? '' : 's'
|
|
||||||
}.`;
|
|
||||||
grunt.log.error(errorMessage);
|
|
||||||
results.reports.forEach(report => {
|
|
||||||
grunt.log.error(JSON.stringify(report, null, 2));
|
|
||||||
});
|
|
||||||
await logForFailure();
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
grunt.log.ok(`${results.passes} tests passed.`);
|
|
||||||
} finally {
|
|
||||||
if (app.isRunning()) {
|
|
||||||
await app.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grunt.registerTask(
|
|
||||||
'unit-tests',
|
|
||||||
'Run unit tests w/Electron',
|
|
||||||
function thisNeeded() {
|
|
||||||
const environment = grunt.option('env') || 'test';
|
|
||||||
promiseToAsyncGruntTask(runTests(environment), this.async());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
grunt.registerTask(
|
|
||||||
'lib-unit-tests',
|
|
||||||
'Run libtextsecure unit tests w/Electron',
|
|
||||||
function thisNeeded() {
|
|
||||||
const environment = grunt.option('env') || 'test-lib';
|
|
||||||
promiseToAsyncGruntTask(runTests(environment), this.async());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
grunt.registerMultiTask(
|
|
||||||
'test-release',
|
|
||||||
'Test packaged releases',
|
|
||||||
function thisNeeded() {
|
|
||||||
const dir = grunt.option('dir') || 'release';
|
|
||||||
const environment = grunt.option('env') || 'production';
|
|
||||||
const config = this.data;
|
|
||||||
const archive = [dir, config.archive].join('/');
|
|
||||||
const files = [
|
|
||||||
'config/default.json',
|
|
||||||
`config/${environment}.json`,
|
|
||||||
`config/local-${environment}.json`,
|
|
||||||
];
|
|
||||||
|
|
||||||
console.log(this.target, archive);
|
|
||||||
const releaseFiles = files.concat(config.files || []);
|
|
||||||
releaseFiles.forEach(fileName => {
|
|
||||||
console.log(fileName);
|
|
||||||
try {
|
|
||||||
asar.statFile(archive, fileName);
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
throw new Error(`Missing file ${fileName}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (config.appUpdateYML) {
|
|
||||||
const appUpdateYML = [dir, config.appUpdateYML].join('/');
|
|
||||||
if (fs.existsSync(appUpdateYML)) {
|
|
||||||
console.log('auto update ok');
|
|
||||||
} else {
|
|
||||||
throw new Error(`Missing auto update config ${appUpdateYML}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const done = this.async();
|
|
||||||
// A simple test to verify a visible window is opened with a title
|
|
||||||
const { Application } = spectron;
|
|
||||||
|
|
||||||
const path = [dir, config.exe].join('/');
|
|
||||||
console.log('Starting path', path);
|
|
||||||
const app = new Application({
|
|
||||||
path,
|
|
||||||
});
|
|
||||||
|
|
||||||
const sleep = millis =>
|
|
||||||
new Promise(resolve => setTimeout(resolve, millis));
|
|
||||||
|
|
||||||
Promise.race([app.start(), sleep(15000)])
|
|
||||||
.then(() => {
|
|
||||||
if (!app.isRunning()) {
|
|
||||||
throw new Error('Application failed to start');
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.client.getWindowCount();
|
|
||||||
})
|
|
||||||
.then(count => {
|
|
||||||
assert.equal(count, 1);
|
|
||||||
console.log('window opened');
|
|
||||||
})
|
|
||||||
.then(() =>
|
|
||||||
// Verify the window's title
|
|
||||||
app.client.waitUntil(
|
|
||||||
async () =>
|
|
||||||
(await app.client.getTitle()) === packageJson.productName,
|
|
||||||
{
|
|
||||||
timeoutMsg: `Expected window title to be ${JSON.stringify(
|
|
||||||
packageJson.productName
|
|
||||||
)}`,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
console.log('title ok');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
assert(
|
|
||||||
app.chromeDriver.logLines.indexOf(`NODE_ENV ${environment}`) > -1
|
|
||||||
);
|
|
||||||
console.log('environment ok');
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
() =>
|
|
||||||
// Successfully completed test
|
|
||||||
app.stop(),
|
|
||||||
error =>
|
|
||||||
// Test failed!
|
|
||||||
app.stop().then(() => {
|
|
||||||
grunt.fail.fatal(`Test failed: ${error.message} ${error.stack}`);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.catch(error => {
|
|
||||||
console.log('Main process logs:');
|
|
||||||
app.client.getMainProcessLogs().then(logs => {
|
|
||||||
logs.forEach(log => {
|
|
||||||
console.log(log);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Test failed!
|
|
||||||
grunt.fail.fatal(`Failure! ${error.message} ${error.stack}`);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
grunt.registerTask('tx', [
|
grunt.registerTask('tx', [
|
||||||
'exec:tx-pull-mostly-translated',
|
'exec:tx-pull-mostly-translated',
|
||||||
'exec:tx-pull-any-existing-translation',
|
'exec:tx-pull-any-existing-translation',
|
||||||
'locale-patch',
|
'locale-patch',
|
||||||
]);
|
]);
|
||||||
grunt.registerTask('dev', ['default', 'watch']);
|
grunt.registerTask('dev', ['default', 'watch']);
|
||||||
grunt.registerTask('test', ['unit-tests', 'lib-unit-tests']);
|
|
||||||
grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
|
grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
|
||||||
grunt.registerTask('default', [
|
grunt.registerTask('default', [
|
||||||
'exec:build-protobuf',
|
'exec:build-protobuf',
|
||||||
|
|
32
app/main.ts
32
app/main.ts
|
@ -23,6 +23,7 @@ import {
|
||||||
screen,
|
screen,
|
||||||
shell,
|
shell,
|
||||||
systemPreferences,
|
systemPreferences,
|
||||||
|
desktopCapturer,
|
||||||
} from 'electron';
|
} from 'electron';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
@ -587,11 +588,10 @@ async function createWindow() {
|
||||||
|
|
||||||
if (getEnvironment() === Environment.Test) {
|
if (getEnvironment() === Environment.Test) {
|
||||||
mainWindow.loadURL(
|
mainWindow.loadURL(
|
||||||
prepareFileUrl([__dirname, '../test/index.html'], moreKeys)
|
prepareFileUrl([__dirname, '../test/index.html'], {
|
||||||
);
|
...moreKeys,
|
||||||
} else if (getEnvironment() === Environment.TestLib) {
|
argv: JSON.stringify(process.argv),
|
||||||
mainWindow.loadURL(
|
})
|
||||||
prepareFileUrl([__dirname, '../libtextsecure/test/index.html'], moreKeys)
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadURL(
|
mainWindow.loadURL(
|
||||||
|
@ -1424,10 +1424,7 @@ app.on('ready', async () => {
|
||||||
|
|
||||||
addSensitivePath(userDataPath);
|
addSensitivePath(userDataPath);
|
||||||
|
|
||||||
if (
|
if (getEnvironment() !== Environment.Test) {
|
||||||
getEnvironment() !== Environment.Test &&
|
|
||||||
getEnvironment() !== Environment.TestLib
|
|
||||||
) {
|
|
||||||
installFileHandler({
|
installFileHandler({
|
||||||
protocol: electronProtocol,
|
protocol: electronProtocol,
|
||||||
userDataPath,
|
userDataPath,
|
||||||
|
@ -2120,3 +2117,20 @@ ipc.handle('show-save-dialog', async (_event, { defaultPath }) => {
|
||||||
defaultPath,
|
defaultPath,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipc.handle('getScreenCaptureSources', async () => {
|
||||||
|
return desktopCapturer.getSources({
|
||||||
|
fetchWindowIcons: true,
|
||||||
|
thumbnailSize: { height: 102, width: 184 },
|
||||||
|
types: ['window', 'screen'],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isTestEnvironment(getEnvironment())) {
|
||||||
|
ipc.handle('ci:test-electron:done', async (_event, info) => {
|
||||||
|
process.stdout.write(
|
||||||
|
`ci:test-electron:done=${JSON.stringify(info)}\n`,
|
||||||
|
() => app.quit()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -2,19 +2,29 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { mkdirSync } from 'fs';
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
|
|
||||||
import { start } from './base_config';
|
import { start } from './base_config';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
|
|
||||||
|
let userData: string | undefined;
|
||||||
// Use separate data directory for benchmarks & development
|
// Use separate data directory for benchmarks & development
|
||||||
if (config.has('storagePath')) {
|
if (config.has('storagePath')) {
|
||||||
app.setPath('userData', String(config.get('storagePath')));
|
userData = String(config.get('storagePath'));
|
||||||
} else if (config.has('storageProfile')) {
|
} else if (config.has('storageProfile')) {
|
||||||
const userData = join(
|
userData = join(
|
||||||
app.getPath('appData'),
|
app.getPath('appData'),
|
||||||
`Signal-${config.get('storageProfile')}`
|
`Signal-${config.get('storageProfile')}`
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userData !== undefined) {
|
||||||
|
try {
|
||||||
|
mkdirSync(userData, { recursive: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to create userData', error?.stack || String(error));
|
||||||
|
}
|
||||||
|
|
||||||
app.setPath('userData', userData);
|
app.setPath('userData', userData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
node: false,
|
|
||||||
mocha: true,
|
|
||||||
},
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'script',
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
strict: 'off',
|
|
||||||
'more/no-then': 'off',
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
assert: true,
|
|
||||||
getString: true,
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,70 +0,0 @@
|
||||||
// Copyright 2015-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global chai */
|
|
||||||
|
|
||||||
mocha.setup('bdd');
|
|
||||||
window.assert = chai.assert;
|
|
||||||
|
|
||||||
const OriginalReporter = mocha._reporter;
|
|
||||||
|
|
||||||
const SauceReporter = function Constructor(runner) {
|
|
||||||
const failedTests = [];
|
|
||||||
|
|
||||||
runner.on('end', () => {
|
|
||||||
window.mochaResults = runner.stats;
|
|
||||||
window.mochaResults.reports = failedTests;
|
|
||||||
});
|
|
||||||
|
|
||||||
runner.on('fail', (test, err) => {
|
|
||||||
const flattenTitles = item => {
|
|
||||||
const titles = [];
|
|
||||||
while (item.parent.title) {
|
|
||||||
titles.push(item.parent.title);
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
item = item.parent;
|
|
||||||
}
|
|
||||||
return titles.reverse();
|
|
||||||
};
|
|
||||||
failedTests.push({
|
|
||||||
name: test.title,
|
|
||||||
result: false,
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
titles: flattenTitles(test),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
|
||||||
new OriginalReporter(runner);
|
|
||||||
};
|
|
||||||
|
|
||||||
SauceReporter.prototype = OriginalReporter.prototype;
|
|
||||||
|
|
||||||
mocha.reporter(SauceReporter);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* global helpers for tests
|
|
||||||
*/
|
|
||||||
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
window.Whisper.events = {
|
|
||||||
on() {},
|
|
||||||
trigger() {},
|
|
||||||
};
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
try {
|
|
||||||
window.SignalContext.log.info('Initializing SQL in renderer');
|
|
||||||
const isTesting = true;
|
|
||||||
await window.Signal.Data.startInRenderer(isTesting);
|
|
||||||
window.SignalContext.log.info('SQL initialized in renderer');
|
|
||||||
} catch (err) {
|
|
||||||
window.SignalContext.log.error(
|
|
||||||
'SQL failed to initialize',
|
|
||||||
err && err.stack ? err.stack : err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await window.Signal.Util.initializeMessageCounter();
|
|
||||||
});
|
|
|
@ -1,59 +0,0 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
window.setImmediate = window.nodeSetImmediate;
|
|
||||||
|
|
||||||
const getKeysForIdentifierMap = {};
|
|
||||||
const messagesSentMap = {};
|
|
||||||
|
|
||||||
const fakeCall = () => Promise.resolve();
|
|
||||||
|
|
||||||
const fakeAPI = {
|
|
||||||
confirmCode: fakeCall,
|
|
||||||
getAttachment: fakeCall,
|
|
||||||
getAvatar: fakeCall,
|
|
||||||
getDevices: fakeCall,
|
|
||||||
// getKeysForIdentifier : fakeCall,
|
|
||||||
getMyKeys: fakeCall,
|
|
||||||
getProfile: fakeCall,
|
|
||||||
getProvisioningResource: fakeCall,
|
|
||||||
putAttachment: fakeCall,
|
|
||||||
registerKeys: fakeCall,
|
|
||||||
requestVerificationSMS: fakeCall,
|
|
||||||
requestVerificationVoice: fakeCall,
|
|
||||||
// sendMessages: fakeCall,
|
|
||||||
setSignedPreKey: fakeCall,
|
|
||||||
|
|
||||||
getKeysForIdentifier(number) {
|
|
||||||
const res = getKeysForIdentifierMap[number];
|
|
||||||
if (res !== undefined) {
|
|
||||||
delete getKeysForIdentifierMap[number];
|
|
||||||
return Promise.resolve(res);
|
|
||||||
}
|
|
||||||
throw new Error('getKeysForIdentfier of unknown/used number');
|
|
||||||
},
|
|
||||||
|
|
||||||
sendMessages(destination, messageArray) {
|
|
||||||
for (let i = 0, max = messageArray.length; i < max; i += 1) {
|
|
||||||
const msg = messageArray[i];
|
|
||||||
if (
|
|
||||||
(msg.type !== 1 && msg.type !== 3) ||
|
|
||||||
msg.destinationDeviceId === undefined ||
|
|
||||||
msg.destinationRegistrationId === undefined ||
|
|
||||||
msg.body === undefined ||
|
|
||||||
msg.timestamp === undefined ||
|
|
||||||
msg.relay !== undefined ||
|
|
||||||
msg.destination !== undefined
|
|
||||||
) {
|
|
||||||
throw new Error('Invalid message');
|
|
||||||
}
|
|
||||||
|
|
||||||
messagesSentMap[`${destination}.${messageArray[i].destinationDeviceId}`] =
|
|
||||||
msg;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
window.WebAPI = {
|
|
||||||
connect: () => fakeAPI,
|
|
||||||
};
|
|
|
@ -1,44 +0,0 @@
|
||||||
<!-- Copyright 2015-2021 Signal Messenger, LLC -->
|
|
||||||
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>libtextsecure test runner</title>
|
|
||||||
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
<div id="tests"></div>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="fake_web_api.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="test.js"></script>
|
|
||||||
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../protocol_wrapper.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../../js/libphonenumber-util.js"
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../../js/components.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="task_with_timeout_test.js"></script>
|
|
||||||
<script type="text/javascript" src="account_manager_test.js"></script>
|
|
||||||
<script type="text/javascript" src="sendmessage_test.js"></script>
|
|
||||||
|
|
||||||
<!-- Uncomment to start tests without code coverage enabled -->
|
|
||||||
<script type="text/javascript">
|
|
||||||
mocha.run();
|
|
||||||
window.Signal.conversationControllerStart();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
16
package.json
16
package.json
|
@ -30,7 +30,8 @@
|
||||||
"prepare-windows-cert": "node scripts/prepare_windows_cert.js",
|
"prepare-windows-cert": "node scripts/prepare_windows_cert.js",
|
||||||
"publish-to-apt": "NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh",
|
"publish-to-apt": "NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh",
|
||||||
"test": "yarn test-node && yarn test-electron",
|
"test": "yarn test-node && yarn test-electron",
|
||||||
"test-electron": "yarn grunt test",
|
"test-electron": "node ts/build/test-electron.js",
|
||||||
|
"test-release": "node ts/build/test-release.js",
|
||||||
"test-node": "electron-mocha --file test/setup-test-node.js --recursive test/app test/modules ts/test-node ts/test-both",
|
"test-node": "electron-mocha --file test/setup-test-node.js --recursive test/app test/modules ts/test-node ts/test-both",
|
||||||
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test-node ts/test-both",
|
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test-node ts/test-both",
|
||||||
"eslint": "eslint --cache .",
|
"eslint": "eslint --cache .",
|
||||||
|
@ -207,7 +208,7 @@
|
||||||
"@types/lru-cache": "5.1.0",
|
"@types/lru-cache": "5.1.0",
|
||||||
"@types/memoizee": "0.4.2",
|
"@types/memoizee": "0.4.2",
|
||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/mocha": "5.0.0",
|
"@types/mocha": "9.0.0",
|
||||||
"@types/mustache": "4.1.2",
|
"@types/mustache": "4.1.2",
|
||||||
"@types/node": "14.14.37",
|
"@types/node": "14.14.37",
|
||||||
"@types/node-fetch": "2.5.7",
|
"@types/node-fetch": "2.5.7",
|
||||||
|
@ -238,6 +239,7 @@
|
||||||
"@types/uuid": "3.4.4",
|
"@types/uuid": "3.4.4",
|
||||||
"@types/webpack-dev-server": "3.11.3",
|
"@types/webpack-dev-server": "3.11.3",
|
||||||
"@types/websocket": "1.0.0",
|
"@types/websocket": "1.0.0",
|
||||||
|
"@types/yargs": "17.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "4.30.0",
|
"@typescript-eslint/eslint-plugin": "4.30.0",
|
||||||
"@typescript-eslint/parser": "4.30.0",
|
"@typescript-eslint/parser": "4.30.0",
|
||||||
"arraybuffer-loader": "1.0.3",
|
"arraybuffer-loader": "1.0.3",
|
||||||
|
@ -250,9 +252,9 @@
|
||||||
"core-js": "2.6.9",
|
"core-js": "2.6.9",
|
||||||
"cross-env": "5.2.0",
|
"cross-env": "5.2.0",
|
||||||
"css-loader": "3.2.0",
|
"css-loader": "3.2.0",
|
||||||
"electron": "15.3.2",
|
"electron": "16.0.4",
|
||||||
"electron-builder": "22.14.5",
|
"electron-builder": "22.14.5",
|
||||||
"electron-mocha": "10.1.0",
|
"electron-mocha": "11.0.2",
|
||||||
"electron-notarize": "0.1.1",
|
"electron-notarize": "0.1.1",
|
||||||
"eslint": "7.7.0",
|
"eslint": "7.7.0",
|
||||||
"eslint-config-airbnb-typescript-prettier": "3.1.0",
|
"eslint-config-airbnb-typescript-prettier": "3.1.0",
|
||||||
|
@ -271,7 +273,7 @@
|
||||||
"grunt-gitinfo": "0.1.9",
|
"grunt-gitinfo": "0.1.9",
|
||||||
"grunt-sass": "3.1.0",
|
"grunt-sass": "3.1.0",
|
||||||
"html-webpack-plugin": "5.3.1",
|
"html-webpack-plugin": "5.3.1",
|
||||||
"mocha": "4.1.0",
|
"mocha": "9.1.3",
|
||||||
"mocha-testcheck": "1.0.0-rc.0",
|
"mocha-testcheck": "1.0.0-rc.0",
|
||||||
"node-gyp": "7.1.2",
|
"node-gyp": "7.1.2",
|
||||||
"node-sass": "6.0.1",
|
"node-sass": "6.0.1",
|
||||||
|
@ -279,11 +281,11 @@
|
||||||
"npm-run-all": "4.1.5",
|
"npm-run-all": "4.1.5",
|
||||||
"nyc": "11.4.1",
|
"nyc": "11.4.1",
|
||||||
"patch-package": "6.4.7",
|
"patch-package": "6.4.7",
|
||||||
|
"playwright": "1.17.1",
|
||||||
"prettier": "2.4.1",
|
"prettier": "2.4.1",
|
||||||
"react-docgen-typescript": "1.2.6",
|
"react-docgen-typescript": "1.2.6",
|
||||||
"sass-loader": "10.2.0",
|
"sass-loader": "10.2.0",
|
||||||
"sinon": "11.1.1",
|
"sinon": "11.1.1",
|
||||||
"spectron": "5.0.0",
|
|
||||||
"style-loader": "1.0.0",
|
"style-loader": "1.0.0",
|
||||||
"terser-webpack-plugin": "5.1.1",
|
"terser-webpack-plugin": "5.1.1",
|
||||||
"ts-loader": "4.1.0",
|
"ts-loader": "4.1.0",
|
||||||
|
@ -303,7 +305,7 @@
|
||||||
"sharp/color/color-string": "1.5.5"
|
"sharp/color/color-string": "1.5.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.5.0"
|
"node": "16.9.1"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"appId": "org.whispersystems.signal-desktop",
|
"appId": "org.whispersystems.signal-desktop",
|
||||||
|
|
|
@ -121,7 +121,7 @@ try {
|
||||||
window.open = () => null;
|
window.open = () => null;
|
||||||
|
|
||||||
// Playwright uses `eval` for `.evaluate()` API
|
// Playwright uses `eval` for `.evaluate()` API
|
||||||
if (!config.enableCI) {
|
if (!config.enableCI && config.environment !== 'test') {
|
||||||
// eslint-disable-next-line no-eval, no-multi-assign
|
// eslint-disable-next-line no-eval, no-multi-assign
|
||||||
window.eval = global.eval = () => null;
|
window.eval = global.eval = () => null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,26 @@
|
||||||
|
|
||||||
/* global window */
|
/* global window */
|
||||||
|
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
window.assert = require('chai').assert;
|
||||||
|
|
||||||
// This is a hack to let us run TypeScript tests in the renderer process. See the
|
// This is a hack to let us run TypeScript tests in the renderer process. See the
|
||||||
// code in `test/index.html`.
|
// code in `test/index.html`.
|
||||||
const pendingDescribeCalls = [];
|
|
||||||
window.describe = (...args) => {
|
|
||||||
pendingDescribeCalls.push(args);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* eslint-disable global-require, import/no-extraneous-dependencies */
|
/* eslint-disable global-require, import/no-extraneous-dependencies */
|
||||||
const fastGlob = require('fast-glob');
|
const fastGlob = require('fast-glob');
|
||||||
|
|
||||||
fastGlob
|
|
||||||
.sync('./ts/test-{both,electron}/**/*_test.js', {
|
|
||||||
absolute: true,
|
|
||||||
cwd: __dirname,
|
|
||||||
})
|
|
||||||
.forEach(require);
|
|
||||||
|
|
||||||
delete window.describe;
|
|
||||||
|
|
||||||
window.test = {
|
window.test = {
|
||||||
pendingDescribeCalls,
|
onComplete(info) {
|
||||||
fastGlob,
|
return ipcRenderer.invoke('ci:test-electron:done', info);
|
||||||
normalizePath: require('normalize-path'),
|
},
|
||||||
fse: require('fs-extra'),
|
prepareTests() {
|
||||||
path: require('path'),
|
fastGlob
|
||||||
basePath: __dirname,
|
.sync('./ts/test-{both,electron}/**/*_test.js', {
|
||||||
attachmentsPath: window.Signal.Migrations.attachmentsPath,
|
absolute: true,
|
||||||
|
cwd: __dirname,
|
||||||
|
})
|
||||||
|
.forEach(require);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -161,11 +161,6 @@
|
||||||
{{/isError}}
|
{{/isError}}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../libtextsecure/test/fake_web_api.js"
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="../js/components.js"></script>
|
<script type="text/javascript" src="../js/components.js"></script>
|
||||||
<script type="text/javascript" src="../ts/backboneJquery.js"></script>
|
<script type="text/javascript" src="../ts/backboneJquery.js"></script>
|
||||||
<script
|
<script
|
||||||
|
@ -173,6 +168,13 @@
|
||||||
src="../js/reliable_trigger.js"
|
src="../js/reliable_trigger.js"
|
||||||
data-cover
|
data-cover
|
||||||
></script>
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="../node_modules/mocha/mocha.js"
|
||||||
|
></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
mocha.setup('bdd');
|
||||||
|
</script>
|
||||||
<script type="text/javascript" src="test.js"></script>
|
<script type="text/javascript" src="test.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="../js/database.js" data-cover></script>
|
<script type="text/javascript" src="../js/database.js" data-cover></script>
|
||||||
|
@ -193,39 +195,13 @@
|
||||||
src="../js/expiring_tap_to_view_messages.js"
|
src="../js/expiring_tap_to_view_messages.js"
|
||||||
data-cover
|
data-cover
|
||||||
></script>
|
></script>
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../js/notifications.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="../js/views/react_wrapper_view.js"
|
src="../js/views/react_wrapper_view.js"
|
||||||
></script>
|
></script>
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../js/views/list_view.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../js/views/contact_list_view.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../js/views/group_member_list_view.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="../js/views/inbox_view.js"
|
|
||||||
data-cover
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="views/whisper_view_test.js"></script>
|
<script type="text/javascript" src="views/whisper_view_test.js"></script>
|
||||||
<script type="text/javascript" src="views/list_view_test.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="libphonenumber_util_test.js"></script>
|
<script type="text/javascript" src="libphonenumber_util_test.js"></script>
|
||||||
<script type="text/javascript" src="reliable_trigger_test.js"></script>
|
<script type="text/javascript" src="reliable_trigger_test.js"></script>
|
||||||
|
@ -236,11 +212,33 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.Signal.conversationControllerStart();
|
window.Signal.conversationControllerStart();
|
||||||
|
|
||||||
window.test.pendingDescribeCalls.forEach(args => {
|
window.test.prepareTests();
|
||||||
describe(...args);
|
delete window.test.prepareTests;
|
||||||
});
|
|
||||||
|
|
||||||
mocha.run();
|
!(function () {
|
||||||
|
const passed = [];
|
||||||
|
const failed = [];
|
||||||
|
|
||||||
|
class Reporter extends Mocha.reporters.HTML {
|
||||||
|
constructor(runner, options) {
|
||||||
|
super(runner, options);
|
||||||
|
|
||||||
|
runner.on('pass', test => passed.push(test.fullTitle()));
|
||||||
|
runner.on('fail', (test, error) => {
|
||||||
|
failed.push({
|
||||||
|
testName: test.fullTitle(),
|
||||||
|
error: error?.stack || String(error),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
runner.on('end', () => window.test.onComplete({ passed, failed }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mocha.reporter(Reporter);
|
||||||
|
|
||||||
|
mocha.run();
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,47 +1,7 @@
|
||||||
// Copyright 2014-2020 Signal Messenger, LLC
|
// Copyright 2014-2020 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* global chai, Whisper, _, Backbone */
|
/* global Whisper, _, Backbone */
|
||||||
|
|
||||||
mocha.setup('bdd');
|
|
||||||
window.assert = chai.assert;
|
|
||||||
|
|
||||||
const OriginalReporter = mocha._reporter;
|
|
||||||
|
|
||||||
const SauceReporter = function Constructor(runner) {
|
|
||||||
const failedTests = [];
|
|
||||||
|
|
||||||
runner.on('end', () => {
|
|
||||||
window.mochaResults = runner.stats;
|
|
||||||
window.mochaResults.reports = failedTests;
|
|
||||||
});
|
|
||||||
|
|
||||||
runner.on('fail', (test, err) => {
|
|
||||||
const flattenTitles = item => {
|
|
||||||
const titles = [];
|
|
||||||
while (item.parent.title) {
|
|
||||||
titles.push(item.parent.title);
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
item = item.parent;
|
|
||||||
}
|
|
||||||
return titles.reverse();
|
|
||||||
};
|
|
||||||
failedTests.push({
|
|
||||||
name: test.title,
|
|
||||||
result: false,
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
titles: flattenTitles(test),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
|
||||||
new OriginalReporter(runner);
|
|
||||||
};
|
|
||||||
|
|
||||||
SauceReporter.prototype = OriginalReporter.prototype;
|
|
||||||
|
|
||||||
mocha.reporter(SauceReporter);
|
|
||||||
|
|
||||||
// Override the database id.
|
// Override the database id.
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
import { execFileSync } from 'child_process';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
const ROOT_DIR = join(__dirname, '..', '..');
|
||||||
|
|
||||||
|
const ELECTRON = join(
|
||||||
|
ROOT_DIR,
|
||||||
|
'node_modules',
|
||||||
|
'.bin',
|
||||||
|
process.platform === 'win32' ? 'electron.cmd' : 'electron'
|
||||||
|
);
|
||||||
|
|
||||||
|
const stdout = execFileSync(ELECTRON, [ROOT_DIR], {
|
||||||
|
cwd: ROOT_DIR,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
NODE_ENV: 'test',
|
||||||
|
},
|
||||||
|
encoding: 'utf8',
|
||||||
|
});
|
||||||
|
|
||||||
|
const match = stdout.match(/ci:test-electron:done=(.*)?\n/);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
throw new Error('No test results were found in stdout');
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
passed,
|
||||||
|
failed,
|
||||||
|
}: {
|
||||||
|
passed: Array<string>;
|
||||||
|
failed: Array<{ testName: string; error: string }>;
|
||||||
|
} = JSON.parse(match[1]);
|
||||||
|
|
||||||
|
const total = passed.length + failed.length;
|
||||||
|
|
||||||
|
for (const { testName, error } of failed) {
|
||||||
|
console.error(`- ${testName}`);
|
||||||
|
console.error(error);
|
||||||
|
console.error('');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Passed ${passed.length} | Failed ${failed.length} | Total ${total}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (failed.length !== 0) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
import asar from 'asar';
|
||||||
|
import assert from 'assert';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { _electron as electron } from 'playwright';
|
||||||
|
|
||||||
|
import packageJson from '../../package.json';
|
||||||
|
|
||||||
|
const ENVIRONMENT = 'production';
|
||||||
|
const RELEASE_DIR = join(__dirname, '..', '..', 'release');
|
||||||
|
|
||||||
|
let archive: string;
|
||||||
|
let exe: string;
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
archive = join(
|
||||||
|
'mac',
|
||||||
|
`${packageJson.productName}.app`,
|
||||||
|
'Contents',
|
||||||
|
'Resources',
|
||||||
|
'app.asar'
|
||||||
|
);
|
||||||
|
exe = join(
|
||||||
|
'mac',
|
||||||
|
`${packageJson.productName}.app`,
|
||||||
|
'Contents',
|
||||||
|
'MacOS',
|
||||||
|
packageJson.productName
|
||||||
|
);
|
||||||
|
} else if (process.platform === 'win32') {
|
||||||
|
archive = join('win-unpacked', 'resources', 'app.asar');
|
||||||
|
exe = join('win-unpacked', `${packageJson.productName}.exe`);
|
||||||
|
} else if (process.platform === 'linux') {
|
||||||
|
archive = join('linux-unpacked', 'resources', 'app.asar');
|
||||||
|
exe = join('linux-unpacked', packageJson.name);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = [
|
||||||
|
join('config', 'default.json'),
|
||||||
|
join('config', `${ENVIRONMENT}.json`),
|
||||||
|
join('config', `local-${ENVIRONMENT}.json`),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const fileName of files) {
|
||||||
|
console.log(`Checking that ${fileName} exists in asar ${archive}`);
|
||||||
|
try {
|
||||||
|
asar.statFile(join(RELEASE_DIR, archive), fileName);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
throw new Error(`Missing file ${fileName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A simple test to verify a visible window is opened with a title
|
||||||
|
const main = async () => {
|
||||||
|
const executablePath = join(RELEASE_DIR, exe);
|
||||||
|
console.log('Starting path', executablePath);
|
||||||
|
const app = await electron.launch({
|
||||||
|
executablePath,
|
||||||
|
locale: 'en',
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Waiting for a first window');
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
await window.waitForLoadState();
|
||||||
|
|
||||||
|
console.log('Checking window title');
|
||||||
|
assert.strictEqual(await window.title(), packageJson.productName);
|
||||||
|
|
||||||
|
await app.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
main().catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
|
@ -9,7 +9,6 @@ export enum Environment {
|
||||||
Production = 'production',
|
Production = 'production',
|
||||||
Staging = 'staging',
|
Staging = 'staging',
|
||||||
Test = 'test',
|
Test = 'test',
|
||||||
TestLib = 'test-lib',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let environment: undefined | Environment;
|
let environment: undefined | Environment;
|
||||||
|
@ -41,4 +40,4 @@ export const parseEnvironment = makeEnumParser(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isTestEnvironment = (env: Environment): boolean =>
|
export const isTestEnvironment = (env: Environment): boolean =>
|
||||||
env === Environment.Test || env === Environment.TestLib;
|
env === Environment.Test;
|
||||||
|
|
|
@ -43,9 +43,7 @@ let globalLogger: undefined | pino.Logger;
|
||||||
let shouldRestart = false;
|
let shouldRestart = false;
|
||||||
|
|
||||||
const isRunningFromConsole =
|
const isRunningFromConsole =
|
||||||
Boolean(process.stdout.isTTY) ||
|
Boolean(process.stdout.isTTY) || getEnvironment() === Environment.Test;
|
||||||
getEnvironment() === Environment.Test ||
|
|
||||||
getEnvironment() === Environment.TestLib;
|
|
||||||
|
|
||||||
export async function initialize(
|
export async function initialize(
|
||||||
getMainWindow: () => undefined | BrowserWindow
|
getMainWindow: () => undefined | BrowserWindow
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright 2020-2021 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { desktopCapturer, ipcRenderer } from 'electron';
|
import type { DesktopCapturerSource } from 'electron';
|
||||||
|
import { ipcRenderer } from 'electron';
|
||||||
import type {
|
import type {
|
||||||
AudioDevice,
|
AudioDevice,
|
||||||
CallId,
|
CallId,
|
||||||
|
@ -1097,11 +1098,8 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPresentingSources(): Promise<Array<PresentableSource>> {
|
async getPresentingSources(): Promise<Array<PresentableSource>> {
|
||||||
const sources = await desktopCapturer.getSources({
|
const sources: ReadonlyArray<DesktopCapturerSource> =
|
||||||
fetchWindowIcons: true,
|
await ipcRenderer.invoke('getScreenCaptureSources');
|
||||||
thumbnailSize: { height: 102, width: 184 },
|
|
||||||
types: ['window', 'screen'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const presentableSources: Array<PresentableSource> = [];
|
const presentableSources: Array<PresentableSource> = [];
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,6 @@ describe('environment utilities', () => {
|
||||||
it('parses "test" as Environment.Test', () => {
|
it('parses "test" as Environment.Test', () => {
|
||||||
assert.equal(parseEnvironment('test'), Environment.Test);
|
assert.equal(parseEnvironment('test'), Environment.Test);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses "test-lib" as Environment.TestLib', () => {
|
|
||||||
assert.equal(parseEnvironment('test-lib'), Environment.TestLib);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isTestEnvironment', () => {
|
describe('isTestEnvironment', () => {
|
||||||
|
@ -52,7 +48,6 @@ describe('environment utilities', () => {
|
||||||
|
|
||||||
it('returns true for test environments', () => {
|
it('returns true for test environments', () => {
|
||||||
assert.isTrue(isTestEnvironment(Environment.Test));
|
assert.isTrue(isTestEnvironment(Environment.Test));
|
||||||
assert.isTrue(isTestEnvironment(Environment.TestLib));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1352,7 +1352,7 @@ describe('calling duck', () => {
|
||||||
|
|
||||||
describe('thunk', () => {
|
describe('thunk', () => {
|
||||||
function noopTest(connectionState: GroupCallConnectionState) {
|
function noopTest(connectionState: GroupCallConnectionState) {
|
||||||
return async function test(this: Mocha.ITestCallbackContext) {
|
return async function test(this: Mocha.Context) {
|
||||||
const dispatch = sinon.spy();
|
const dispatch = sinon.spy();
|
||||||
|
|
||||||
await peekNotConnectedGroupCall({
|
await peekNotConnectedGroupCall({
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* global textsecure, WebAPI */
|
import { assert } from 'chai';
|
||||||
/* eslint-disable no-console */
|
|
||||||
|
import MessageSender from '../../textsecure/SendMessage';
|
||||||
|
import type { WebAPIType } from '../../textsecure/WebAPI';
|
||||||
|
|
||||||
const BUCKET_SIZES = [
|
const BUCKET_SIZES = [
|
||||||
541, 568, 596, 626, 657, 690, 725, 761, 799, 839, 881, 925, 972, 1020, 1071,
|
541, 568, 596, 626, 657, 690, 725, 761, 799, 839, 881, 925, 972, 1020, 1071,
|
||||||
|
@ -34,17 +36,11 @@ const BUCKET_SIZES = [
|
||||||
80095580, 84100359, 88305377, 92720646, 97356678, 102224512, 107335738,
|
80095580, 84100359, 88305377, 92720646, 97356678, 102224512, 107335738,
|
||||||
];
|
];
|
||||||
|
|
||||||
describe('sendmessage', () => {
|
describe('SendMessage', () => {
|
||||||
let originalWebAPIConnect = null;
|
let sendMessage: MessageSender;
|
||||||
let sendmessage = null;
|
|
||||||
before(() => {
|
|
||||||
originalWebAPIConnect = WebAPI.connect;
|
|
||||||
WebAPI.connect = () => null;
|
|
||||||
|
|
||||||
sendmessage = new textsecure.MessageSender();
|
before(() => {
|
||||||
});
|
sendMessage = new MessageSender({} as unknown as WebAPIType);
|
||||||
after(() => {
|
|
||||||
WebAPI.connect = originalWebAPIConnect;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#_getAttachmentSizeBucket', () => {
|
describe('#_getAttachmentSizeBucket', () => {
|
||||||
|
@ -52,7 +48,7 @@ describe('sendmessage', () => {
|
||||||
for (let size = 0, max = BUCKET_SIZES[0]; size < max; size += 1) {
|
for (let size = 0, max = BUCKET_SIZES[0]; size < max; size += 1) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
BUCKET_SIZES[0],
|
BUCKET_SIZES[0],
|
||||||
sendmessage._getAttachmentSizeBucket(size)
|
sendMessage._getAttachmentSizeBucket(size)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -60,17 +56,18 @@ describe('sendmessage', () => {
|
||||||
it('properly calculates entire table', () => {
|
it('properly calculates entire table', () => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
|
const failures = new Array<string>();
|
||||||
for (let i = 0, max = BUCKET_SIZES.length - 1; i < max; i += 1) {
|
for (let i = 0, max = BUCKET_SIZES.length - 1; i < max; i += 1) {
|
||||||
// Exact
|
// Exact
|
||||||
if (
|
if (
|
||||||
BUCKET_SIZES[i] !==
|
BUCKET_SIZES[i] !==
|
||||||
sendmessage._getAttachmentSizeBucket(BUCKET_SIZES[i])
|
sendMessage._getAttachmentSizeBucket(BUCKET_SIZES[i])
|
||||||
) {
|
) {
|
||||||
count += 1;
|
count += 1;
|
||||||
console.log(
|
failures.push(
|
||||||
`${
|
`${
|
||||||
BUCKET_SIZES[i]
|
BUCKET_SIZES[i]
|
||||||
} does not equal ${sendmessage._getAttachmentSizeBucket(
|
} does not equal ${sendMessage._getAttachmentSizeBucket(
|
||||||
BUCKET_SIZES[i]
|
BUCKET_SIZES[i]
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
|
@ -79,13 +76,13 @@ describe('sendmessage', () => {
|
||||||
// Just under
|
// Just under
|
||||||
if (
|
if (
|
||||||
BUCKET_SIZES[i] !==
|
BUCKET_SIZES[i] !==
|
||||||
sendmessage._getAttachmentSizeBucket(BUCKET_SIZES[i] - 1)
|
sendMessage._getAttachmentSizeBucket(BUCKET_SIZES[i] - 1)
|
||||||
) {
|
) {
|
||||||
count += 1;
|
count += 1;
|
||||||
console.log(
|
failures.push(
|
||||||
`${
|
`${
|
||||||
BUCKET_SIZES[i]
|
BUCKET_SIZES[i]
|
||||||
} does not equal ${sendmessage._getAttachmentSizeBucket(
|
} does not equal ${sendMessage._getAttachmentSizeBucket(
|
||||||
BUCKET_SIZES[i] - 1
|
BUCKET_SIZES[i] - 1
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
|
@ -94,21 +91,20 @@ describe('sendmessage', () => {
|
||||||
// Just over
|
// Just over
|
||||||
if (
|
if (
|
||||||
BUCKET_SIZES[i + 1] !==
|
BUCKET_SIZES[i + 1] !==
|
||||||
sendmessage._getAttachmentSizeBucket(BUCKET_SIZES[i] + 1)
|
sendMessage._getAttachmentSizeBucket(BUCKET_SIZES[i] + 1)
|
||||||
) {
|
) {
|
||||||
count += 1;
|
count += 1;
|
||||||
console.log(
|
failures.push(
|
||||||
`${
|
`${
|
||||||
BUCKET_SIZES[i + 1]
|
BUCKET_SIZES[i + 1]
|
||||||
} does not equal ${sendmessage._getAttachmentSizeBucket(
|
} does not equal ${sendMessage._getAttachmentSizeBucket(
|
||||||
BUCKET_SIZES[i] + 1
|
BUCKET_SIZES[i] + 1
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Failures: ${count}`);
|
assert.strictEqual(count, 0, failures.join('\n'));
|
||||||
assert.strictEqual(count, 0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
File diff suppressed because it is too large
Load Diff
|
@ -105,6 +105,7 @@ const excludedFilesRegexp = RegExp(
|
||||||
|
|
||||||
// Modules used only in test/development scenarios
|
// Modules used only in test/development scenarios
|
||||||
'^node_modules/@babel/.+',
|
'^node_modules/@babel/.+',
|
||||||
|
'^node_modules/@chanzuckerberg/axe-storybook-testing/.+',
|
||||||
'^node_modules/@svgr/.+',
|
'^node_modules/@svgr/.+',
|
||||||
'^node_modules/@types/.+',
|
'^node_modules/@types/.+',
|
||||||
'^node_modules/@webassemblyjs/.+',
|
'^node_modules/@webassemblyjs/.+',
|
||||||
|
@ -116,8 +117,6 @@ const excludedFilesRegexp = RegExp(
|
||||||
'^node_modules/ansi-colors/.+',
|
'^node_modules/ansi-colors/.+',
|
||||||
'^node_modules/anymatch/.+',
|
'^node_modules/anymatch/.+',
|
||||||
'^node_modules/app-builder-lib/.+',
|
'^node_modules/app-builder-lib/.+',
|
||||||
'^node_modules/archiver-utils/.+', // Used by spectron
|
|
||||||
'^node_modules/archiver/.+', // Used by spectron
|
|
||||||
'^node_modules/asn1\\.js/.+',
|
'^node_modules/asn1\\.js/.+',
|
||||||
'^node_modules/autoprefixer/.+',
|
'^node_modules/autoprefixer/.+',
|
||||||
'^node_modules/babel.+',
|
'^node_modules/babel.+',
|
||||||
|
@ -130,6 +129,7 @@ const excludedFilesRegexp = RegExp(
|
||||||
'^node_modules/builder-util/.+',
|
'^node_modules/builder-util/.+',
|
||||||
'^node_modules/catharsis/.+',
|
'^node_modules/catharsis/.+',
|
||||||
'^node_modules/chai/.+',
|
'^node_modules/chai/.+',
|
||||||
|
'^node_modules/chokidar/.+',
|
||||||
'^node_modules/clean-css/.+',
|
'^node_modules/clean-css/.+',
|
||||||
'^node_modules/cli-table2/.+',
|
'^node_modules/cli-table2/.+',
|
||||||
'^node_modules/cliui/.+',
|
'^node_modules/cliui/.+',
|
||||||
|
@ -161,10 +161,13 @@ const excludedFilesRegexp = RegExp(
|
||||||
'^node_modules/@typescript-eslint.+',
|
'^node_modules/@typescript-eslint.+',
|
||||||
'^node_modules/esprima/.+',
|
'^node_modules/esprima/.+',
|
||||||
'^node_modules/express/.+',
|
'^node_modules/express/.+',
|
||||||
|
'^node_modules/fast-glob/.+',
|
||||||
'^node_modules/file-loader/.+',
|
'^node_modules/file-loader/.+',
|
||||||
'^node_modules/file-system-cache/.+', // Currently only used in storybook
|
'^node_modules/file-system-cache/.+', // Currently only used in storybook
|
||||||
'^node_modules/finalhandler/.+',
|
'^node_modules/finalhandler/.+',
|
||||||
|
'^node_modules/foreground-chat/.+',
|
||||||
'^node_modules/fsevents/.+',
|
'^node_modules/fsevents/.+',
|
||||||
|
'^node_modules/gauge/.+',
|
||||||
'^node_modules/global-agent/.+',
|
'^node_modules/global-agent/.+',
|
||||||
'^node_modules/globule/.+',
|
'^node_modules/globule/.+',
|
||||||
'^node_modules/grunt-cli/.+',
|
'^node_modules/grunt-cli/.+',
|
||||||
|
@ -208,6 +211,8 @@ const excludedFilesRegexp = RegExp(
|
||||||
'^node_modules/optionator/.+',
|
'^node_modules/optionator/.+',
|
||||||
'^node_modules/plist/.+',
|
'^node_modules/plist/.+',
|
||||||
'^node_modules/phantomjs-prebuilt/.+',
|
'^node_modules/phantomjs-prebuilt/.+',
|
||||||
|
'^node_modules/playwright/.+',
|
||||||
|
'^node_modules/playwright-core/.+',
|
||||||
'^node_modules/postcss.+',
|
'^node_modules/postcss.+',
|
||||||
'^node_modules/preserve/.+',
|
'^node_modules/preserve/.+',
|
||||||
'^node_modules/prettier/.+',
|
'^node_modules/prettier/.+',
|
||||||
|
@ -233,7 +238,6 @@ const excludedFilesRegexp = RegExp(
|
||||||
'^node_modules/snapdragon-util/.+',
|
'^node_modules/snapdragon-util/.+',
|
||||||
'^node_modules/snapdragon/.+',
|
'^node_modules/snapdragon/.+',
|
||||||
'^node_modules/sockjs-client/.+',
|
'^node_modules/sockjs-client/.+',
|
||||||
'^node_modules/spectron/.+',
|
|
||||||
'^node_modules/style-loader/.+',
|
'^node_modules/style-loader/.+',
|
||||||
'^node_modules/svgo/.+',
|
'^node_modules/svgo/.+',
|
||||||
'^node_modules/terser/.+',
|
'^node_modules/terser/.+',
|
||||||
|
|
Loading…
Reference in New Issue