😉
Electron でも Claude Code に Playwight MCPを使わせたい
ElectronアプリをClaude Codeに書かせています。
今までUIの部分の動作確認を人間である私の目を通すか、スクリーンショットを通してやっていたのですが、ふと思いました。
ElectronだってまあUIはWebなんだし、Playwight MCPを使わせればClaude自身にスクリーンショットを撮らせたり操作させたりして開発が捗るのでは?
早速やってみたのですが、コンテンツがほとんど表示されません。
Electron由来のコードがundefinedなのでそこでエラーになってしまいます。
ぐぬぬぬ。そこでひらめきました。
そうだ、ElectronオブジェクトのMockをぶっ刺せばいいのでは?
やってみたらできた
ということでやってみたのがこのコミットです。
特に重要な部分だけ抜き出します。
export const createElectronMock = () => ({
ipcRenderer: {
on: (channel: string, listener: Listener) => {
console.log(`[Mock] ipcRenderer.on: ${channel}`)
addListener(channel, listener)
return () => removeListener(channel, listener) // cleanup function
},
send: (channel: string, ...args: unknown[]) => {
console.log(`[Mock] ipcRenderer.send: ${channel}`, args)
// windowReadyが送信されたら、handleWindowReadyを処理する
if (channel === 'windowReady') {
handleWindowReady()
}
// その他のコマンドは単にログを出力
const noOpCommands = [
'activeWindow',
'andMore...'
]
if (noOpCommands.includes(channel)) {
console.log(`[Mock] ${channel} command executed (no-op in mock mode)`)
}
},
removeListener: (channel: string, listener: Listener) => {
console.log(`[Mock] ipcRenderer.removeListener: ${channel}`)
removeListener(channel, listener)
},
invoke: async (channel: string, ...args: unknown[]) => {
console.log(`[Mock] ipcRenderer.invoke: ${channel}`, args)
return null
}
}
})
/**
* Inject mocks into window object if Electron APIs are not available
* Electron APIが利用できない場合、windowオブジェクトにモックを注入
*/
export const injectElectronMocks = () => {
if (typeof window === 'undefined') return
// window.electron のモック
if (!window.electron) {
Object.defineProperty(window, 'electron', {
value: createElectronMock(),
writable: true,
configurable: true
})
console.log('[Mock] Injected window.electron mock')
}
}
これでダミーのElectronオブジェクトを作って、 injectElectronMocks を window.electron に差し込んでやればブラウザからアクセスしたときも即死しないようになります。
必要に応じて、 window.electron.send を拡張したり window.storeを定義するなどすると、案外それっぽく動くようになりました。
種が割れてしまえばなんてことはないですが、結構ちゃんと動くものですね。
Discussion