Files
makelore/tests/e2e/context-menu.spec.ts

97 lines
3.0 KiB
TypeScript

import type { ElectronApplication } from '@playwright/test';
import { closeElectronApp, expect, getStableWindow, test } from './fixtures/electron';
type ContextMenuProbe = {
popupCount: number;
template: Array<{
label: string | null;
role: string | null;
type: string;
}>;
};
async function installContextMenuProbe(app: ElectronApplication): Promise<void> {
await app.evaluate(({ Menu }) => {
const probe: ContextMenuProbe = {
popupCount: 0,
template: [],
};
const globalWithProbe = globalThis as typeof globalThis & {
__makeloreContextMenuProbe?: ContextMenuProbe;
};
globalWithProbe.__makeloreContextMenuProbe = probe;
Menu.buildFromTemplate = ((template) => {
probe.template = template.map((item) => ({
label: item.label ?? null,
role: item.role ?? null,
type: item.type ?? 'normal',
}));
return {
popup: () => {
probe.popupCount += 1;
},
} as unknown as Electron.Menu;
}) as typeof Menu.buildFromTemplate;
});
}
async function readContextMenuProbe(app: ElectronApplication): Promise<ContextMenuProbe | null> {
return await app.evaluate(() => {
const globalWithProbe = globalThis as typeof globalThis & {
__makeloreContextMenuProbe?: ContextMenuProbe;
};
return globalWithProbe.__makeloreContextMenuProbe ?? null;
});
}
test.describe('Makelore text context menu', () => {
test('opens native editing actions for Code and Design textareas', async ({ launchElectronApp }) => {
const app = await launchElectronApp({ skipSetup: true });
try {
const page = await getStableWindow(app);
await installContextMenuProbe(app);
await page.evaluate(() => {
const composerIds = [
'context-menu-e2e-code-composer',
'design-chat-composer',
];
for (const [index, id] of composerIds.entries()) {
const textarea = document.createElement('textarea');
textarea.id = id;
textarea.style.position = 'fixed';
textarea.style.inset = `${80 + index * 80}px auto auto 80px`;
textarea.style.zIndex = '2147483647';
document.body.append(textarea);
}
});
for (const selector of [
'#context-menu-e2e-code-composer',
'#design-chat-composer',
]) {
const textarea = page.locator(selector);
await textarea.fill('Makelore');
await textarea.selectText();
await textarea.click({ button: 'right' });
}
await expect.poll(async () => await readContextMenuProbe(app)).toEqual({
popupCount: 2,
template: [
{ label: '剪切', role: 'cut', type: 'normal' },
{ label: '复制', role: 'copy', type: 'normal' },
{ label: '粘贴', role: 'paste', type: 'normal' },
{ label: null, role: null, type: 'separator' },
{ label: '全选', role: 'selectAll', type: 'normal' },
],
});
} finally {
await closeElectronApp(app);
}
});
});