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 { 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 { 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); } }); });