Files
zn-ai/packages/electron-chrome-extensions/spec/chrome-contextMenus-spec.ts
2025-11-15 22:41:50 +08:00

99 lines
3.5 KiB
TypeScript

import { expect } from 'chai'
import { ipcMain } from 'electron'
import { once } from 'node:events'
import { useExtensionBrowser, useServer } from './hooks'
import { uuid } from './spec-helpers'
describe('chrome.contextMenus', () => {
const server = useServer()
const browser = useExtensionBrowser({
url: server.getUrl,
extensionName: 'rpc',
})
const getContextMenuItems = async () => {
// TODO: why is this needed since upgrading to Electron 22?
await new Promise((resolve) => setTimeout(resolve, 1000))
const contextMenuPromise = once(browser.webContents, 'context-menu')
// Simulate right-click to create context-menu event.
const opts = { x: 0, y: 0, button: 'right' as any }
browser.webContents.sendInputEvent({ ...opts, type: 'mouseDown' })
browser.webContents.sendInputEvent({ ...opts, type: 'mouseUp' })
const [, params] = await contextMenuPromise
return browser.extensions.getContextMenuItems(browser.webContents, params)
}
describe('create()', () => {
it('creates item with label', async () => {
const id = uuid()
const title = 'ヤッホー'
await browser.crx.exec('contextMenus.create', { id, title })
const items = await getContextMenuItems()
expect(items).to.have.lengthOf(1)
expect(items[0].id).to.equal(id)
expect(items[0].label).to.equal(title)
})
it('creates a child item', async () => {
const parentId = uuid()
const id = uuid()
await browser.crx.exec('contextMenus.create', { id: parentId, title: 'parent' })
await browser.crx.exec('contextMenus.create', { id, parentId, title: 'child' })
const items = await getContextMenuItems()
expect(items).to.have.lengthOf(1)
expect(items[0].label).to.equal('parent')
expect(items[0].submenu).to.be.an('object')
expect(items[0].submenu!.items).to.have.lengthOf(1)
expect(items[0].submenu!.items[0].label).to.equal('child')
})
it('groups multiple top-level items', async () => {
await browser.crx.exec('contextMenus.create', { id: uuid(), title: 'one' })
await browser.crx.exec('contextMenus.create', { id: uuid(), title: 'two' })
const items = await getContextMenuItems()
expect(items).to.have.lengthOf(1)
expect(items[0].label).to.equal(browser.extension.name)
expect(items[0].submenu).to.be.an('object')
expect(items[0].submenu!.items).to.have.lengthOf(2)
expect(items[0].submenu!.items[0].label).to.equal('one')
expect(items[0].submenu!.items[1].label).to.equal('two')
})
it('invokes the create callback', async () => {
const ipcName = 'create-callback'
await browser.crx.exec('contextMenus.create', {
title: 'callback',
onclick: { __IPC_FN__: ipcName },
})
const items = await getContextMenuItems()
const p = once(ipcMain, ipcName)
items[0].click()
await p
})
})
describe('remove()', () => {
it('removes item', async () => {
const id = uuid()
await browser.crx.exec('contextMenus.create', { id })
await browser.crx.exec('contextMenus.remove', id)
const items = await getContextMenuItems()
expect(items).to.be.empty
})
})
describe('removeAll()', () => {
it('removes all items', async () => {
await browser.crx.exec('contextMenus.create', {})
await browser.crx.exec('contextMenus.create', {})
await browser.crx.exec('contextMenus.removeAll')
const items = await getContextMenuItems()
expect(items).to.be.empty
})
})
})