97 lines
3.0 KiB
TypeScript
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);
|
|
}
|
|
});
|
|
});
|