fix: restore native text context menu
This commit is contained in:
85
tests/e2e/context-menu.spec.ts
Normal file
85
tests/e2e/context-menu.spec.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
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 editable text', async ({ launchElectronApp }) => {
|
||||
const app = await launchElectronApp({ skipSetup: true });
|
||||
|
||||
try {
|
||||
const page = await getStableWindow(app);
|
||||
await installContextMenuProbe(app);
|
||||
await page.evaluate(() => {
|
||||
const input = document.createElement('input');
|
||||
input.id = 'context-menu-e2e-input';
|
||||
input.style.position = 'fixed';
|
||||
input.style.inset = '80px auto auto 80px';
|
||||
input.style.zIndex = '2147483647';
|
||||
|
||||
document.body.append(input);
|
||||
});
|
||||
|
||||
const input = page.locator('#context-menu-e2e-input');
|
||||
await input.fill('Makelore');
|
||||
await input.selectText();
|
||||
await input.click({ button: 'right' });
|
||||
|
||||
await expect.poll(async () => await readContextMenuProbe(app)).toEqual({
|
||||
popupCount: 1,
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user