vite-electron-builder icon indicating copy to clipboard operation
vite-electron-builder copied to clipboard

main package test failes with electron-store

Open Crease29 opened this issue 4 months ago • 2 comments

Describe the bug The following error occurs when trying to run the test:main script with electron-store in use.

 FAIL  tests/unit.spec.ts [ tests/unit.spec.ts ]
SyntaxError: Named export 'app' not found. The requested module 'electron' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'electron';

 ❯ src/store.ts:2:31
      1| import {ipcMain, type IpcMainEvent, type IpcMainInvokeEvent} from 'electron';
      2| import Store from 'electron-store';
       |                               ^
      3|
      4| const configStore = new Store({

To Reproduce Steps to reproduce the behavior:

  1. Install electron-store
  2. Use store in main process:
// packages/main/src/store.ts
import {ipcMain, type IpcMainEvent, type IpcMainInvokeEvent} from 'electron';
import Store from 'electron-store';

const configStore = new Store({
  accessPropertiesByDotNotation: true,
  migrations: {
    '0.0.1': store => {
      store.clear();
    },
  },
});

ipcMain.on('set-store', (event: IpcMainEvent, args) => {
  configStore.set({[args.key]: args.value});
});

ipcMain.handle('get-store', (event: IpcMainInvokeEvent, key: string) => {
  return configStore.get(key);
});

ipcMain.handle('has-store', (event: IpcMainInvokeEvent, key: string) => {
  return configStore.has(key);
});

ipcMain.handle('delete-store', (event: IpcMainInvokeEvent, key: string) => {
  return configStore.delete(key);
});

export {configStore};
// packages/main/src/index.ts
// ...
import './store'; // Add to imports
// ...
  1. Add ipcMain mock to unit.spec.ts
vi.mock('electron', () => {
  // Use "as unknown as" because vi.fn() does not have static methods
  const bw = vi.fn() as unknown as MockedClass<typeof BrowserWindow>;
  bw.getAllWindows = vi.fn(() => bw.mock.instances);
  bw.prototype.loadURL = vi.fn((_: string, __?: Electron.LoadURLOptions) => Promise.resolve());
  bw.prototype.loadFile = vi.fn((_: string, __?: Electron.LoadFileOptions) => Promise.resolve());
  // Use "any" because the on function is overloaded
  bw.prototype.on = vi.fn<never>();
  bw.prototype.destroy = vi.fn();
  bw.prototype.isDestroyed = vi.fn();
  bw.prototype.isMinimized = vi.fn();
  bw.prototype.isMaximized = vi.fn();
  bw.prototype.focus = vi.fn();
  bw.prototype.restore = vi.fn();

  const app: Pick<Electron.App, 'getAppPath'> = {
    getAppPath(): string {
      return '';
    },
  };
  const ipcMain: Pick<Electron.IpcMain, 'on' | 'handle'> = {
    on: vi.fn(),
    handle: vi.fn(),
  };

  return {BrowserWindow: bw, app, ipcMain};
});
  1. Run npm run test:main

Expected behavior The test should run through, even with external libraries being used. If there's something to add to the electron mock in packages/main/tests/unit.spec.ts when using external libraries, it would be nice to add that to a documentation.

Screenshots image

Additional context I'm using the latest version of this template.

Crease29 avatar Oct 13 '24 10:10 Crease29