This commit bumps Electron and related dependencies to their latest
versions to leverage native ESM support. It adjusts build configuration
to use native ESM support instead of relying on CommonJS bundling.
Key changes:
- Bump Electron to latest v29.
Electron v28 ships with native ESM/ECMAScript modules support.
Details on Electron ESM support:
- electron/electron#21457
- electron/electron#37535
- Bump `electron-builder` to latest v24.13.
`electron-builder` is used to package and publish the application.
It supports ESM since 24.10.
Details on `electron-builder` ESM support:
- electron-userland/electron-builder#7936
- electron-userland/electron-builder#7935
- Bump `electron-log` to latest v5.1.
`electron-log` supports ESM since version 5.0.4.
Details on `electron-log` ESM support:
- megahertz/electron-log#390.
- Change `electron-vite` configuration to bundle as ESM instead of
CommonJS to leverage Electron's native ESM support.
Other supporting changes:
- Add type hint for electron-builder configuration file.
- Update import statements for `electron-updater` as it still is a
CommonJS module and does not support ESM.
Details:
- electron-userland/electron-builder#7976
- Improve `electron-builder` configuration file to dynamically locate
main entry files, supporting various JavaScript file extensions
(`.js`, `.mjs` and `.cjs`) to facilitate easier future changes.
- Change comment about Electron process-specific module alias
registration. This issue has been fixed in `electron-vite`, but
subpath module imports for Electron still do not work when building
tests (`npm run test:unit`).
Details:
- alex8088/electron-vite#372
- Add `electron-log` in bundling process instead of externalizing to
workaround Electron ESM loader issues with subpath imports (inability
to do `electron-log/main`).
Details:
- alex8088/electron-vite#401
- electron/electron#41241
- Improve desktop runtime error checks' assertion message for better
clarity.
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import {
|
|
describe, it, beforeAll, afterAll,
|
|
} from 'vitest';
|
|
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
|
import { main } from './check-desktop-runtime-errors/main';
|
|
import { COMMAND_LINE_FLAGS, CommandLineFlag } from './check-desktop-runtime-errors/cli-args';
|
|
|
|
describe('desktop runtime error checks', () => {
|
|
const { waitForExitCode } = useInterceptedProcessExitOrCompletion(beforeAll, afterAll);
|
|
it('should successfully execute the main function and exit with a zero status code', async () => {
|
|
// arrange
|
|
setCommandLineFlagsFromEnvironmentVariables();
|
|
// act
|
|
const exitCode = await waitForExitCode(
|
|
() => main(),
|
|
);
|
|
// assert
|
|
expect(exitCode).to.equal(0, formatAssertionMessage([
|
|
`Test failed with exit code ${exitCode}; expected 0.`,
|
|
'Examine preceding logs to identify errors.',
|
|
]));
|
|
}, {
|
|
timeout: 60 /* minutes */ * 60000,
|
|
});
|
|
});
|
|
|
|
function useInterceptedProcessExitOrCompletion(
|
|
beforeTest: (callback: () => void) => void,
|
|
afterTest: (callback: () => void) => void,
|
|
) {
|
|
const originalFunction = global.process.exit;
|
|
let isExitCodeReceived = false;
|
|
let exitCodeResolver: (value: number | undefined) => void;
|
|
const waitForExitCode = (runner: () => Promise<void>) => new Promise<number | undefined>(
|
|
(resolve, reject) => {
|
|
exitCodeResolver = resolve;
|
|
runner()
|
|
.catch((error) => {
|
|
if (isExitCodeReceived) {
|
|
return;
|
|
}
|
|
console.error('Process did not call `process.exit` but threw an error:', error);
|
|
reject(error);
|
|
})
|
|
.then(() => {
|
|
if (isExitCodeReceived) {
|
|
return;
|
|
}
|
|
console.log('Process completed without calling `process.exit`. Treating as `0` exit code.');
|
|
exitCodeResolver(0);
|
|
});
|
|
},
|
|
);
|
|
beforeTest(() => {
|
|
global.process.exit = (code?: number): never => {
|
|
exitCodeResolver(code);
|
|
isExitCodeReceived = true;
|
|
return undefined as never;
|
|
};
|
|
});
|
|
afterTest(() => {
|
|
global.process.exit = originalFunction;
|
|
});
|
|
return {
|
|
waitForExitCode,
|
|
};
|
|
}
|
|
|
|
/*
|
|
Map environment variables to CLI arguments for compatibility with Vitest.
|
|
*/
|
|
function setCommandLineFlagsFromEnvironmentVariables() {
|
|
const flagEnvironmentVariableKeyMappings: {
|
|
readonly [key in CommandLineFlag]: string;
|
|
} = {
|
|
[CommandLineFlag.ForceRebuild]: 'BUILD',
|
|
[CommandLineFlag.TakeScreenshot]: 'SCREENSHOT',
|
|
};
|
|
Object.entries(flagEnvironmentVariableKeyMappings)
|
|
.forEach(([flag, environmentVariableKey]) => {
|
|
if (process.env[environmentVariableKey] !== undefined) {
|
|
process.argv = [
|
|
...process.argv,
|
|
COMMAND_LINE_FLAGS[flag],
|
|
];
|
|
}
|
|
});
|
|
}
|