1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-18 09:35:20 +02:00
joplin/packages/app-desktop/integration-tests/util/test.ts
Henry Heino 13d8fbbd65
Chore: Desktop: Fix test failures due to race condition (#11417)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-20 11:35:22 +00:00

125 lines
3.6 KiB
TypeScript

import { resolve, join, dirname } from 'path';
import { remove, mkdirp } from 'fs-extra';
import { _electron as electron, Page, ElectronApplication, test as base } from '@playwright/test';
import uuid from '@joplin/lib/uuid';
import createStartupArgs from './createStartupArgs';
import firstNonDevToolsWindow from './firstNonDevToolsWindow';
import setDarkMode from './setDarkMode';
type StartWithPluginsResult = { app: ElectronApplication; mainWindow: Page };
type JoplinFixtures = {
profileDirectory: string;
electronApp: ElectronApplication;
startAppWithPlugins: (pluginPaths: string[])=> Promise<StartWithPluginsResult>;
startupPluginsLoaded: Promise<void>;
mainWindow: Page;
};
// A custom fixture that loads an electron app. See
// https://playwright.dev/docs/test-fixtures
const getAndResizeMainWindow = async (electronApp: ElectronApplication) => {
const mainWindow = await firstNonDevToolsWindow(electronApp);
// Setting the viewport size helps keep test environments consistent.
await mainWindow.setViewportSize({
width: 1200,
height: 800,
});
return mainWindow;
};
const waitForMainMessage = (electronApp: ElectronApplication, messageId: string) => {
return electronApp.evaluate(({ ipcMain }, messageId) => {
return new Promise<void>(resolve => {
ipcMain.once(messageId, () => resolve());
});
}, messageId);
};
const waitForAppLoaded = async (electronApp: ElectronApplication) => {
await waitForMainMessage(electronApp, 'startup-finished');
};
const waitForStartupPlugins = async (electronApp: ElectronApplication) => {
await waitForMainMessage(electronApp, 'startup-plugins-loaded');
};
const testDir = dirname(__dirname);
export const test = base.extend<JoplinFixtures>({
// Playwright fails if we don't use the object destructuring
// pattern in the first argument.
//
// See https://github.com/microsoft/playwright/issues/8798
//
// eslint-disable-next-line no-empty-pattern
profileDirectory: async ({ }, use) => {
const profilePath = resolve(join(testDir, 'test-profile'));
const profileSubdir = join(profilePath, uuid.createNano());
await mkdirp(profileSubdir);
await use(profileSubdir);
await remove(profileSubdir);
},
electronApp: async ({ profileDirectory }, use) => {
const startupArgs = createStartupArgs(profileDirectory);
const electronApp = await electron.launch({ args: startupArgs });
const startupPromise = waitForAppLoaded(electronApp);
await setDarkMode(electronApp, false);
await startupPromise;
await use(electronApp);
await electronApp.firstWindow();
await electronApp.close();
},
startAppWithPlugins: async ({ profileDirectory }, use) => {
const startupArgs = createStartupArgs(profileDirectory);
let electronApp: ElectronApplication;
await use(async (pluginPaths: string[]) => {
if (electronApp) {
throw new Error('Electron app already created');
}
electronApp = await electron.launch({
args: [
...startupArgs,
'--dev-plugins',
pluginPaths.map(path => resolve(testDir, path)).join(','),
],
});
const startupPromise = waitForAppLoaded(electronApp);
const mainWindowPromise = getAndResizeMainWindow(electronApp);
await waitForStartupPlugins(electronApp);
await startupPromise;
return {
app: electronApp,
mainWindow: await mainWindowPromise,
};
});
if (electronApp) {
await electronApp.firstWindow();
await electronApp.close();
}
},
startupPluginsLoaded: async ({ electronApp }, use) => {
await use(waitForStartupPlugins(electronApp));
},
mainWindow: async ({ electronApp }, use) => {
await use(await getAndResizeMainWindow(electronApp));
},
});
export { default as expect } from './extendedExpect';