Skip to content

Commit 0a87fbb

Browse files
committed
ElectronでもPlaywightMCPしたい
1 parent 611e0a3 commit 0a87fbb

8 files changed

Lines changed: 89 additions & 15 deletions

File tree

‎.claude/settings.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"Bash(mise:run build)",
77
"Bash(mise:run typecheck)",
88
"Bash(mise:run typecheck:node)",
9-
"Bash(mise:run typecheck:renderer)",
9+
"Bash(mise:run typecheck:web)",
1010

1111
"Bash(mise:run lint)",
1212
"Bash(mise:run format)",

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ out
99
.env
1010
icon_cache/
1111
taskbar_mac_cert.p12
12+
.playwright-mcp/

‎CLAUDE.md‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Taskbar.fm is an Electron application that brings Windows-like taskbar functiona
4646
If the TaskbarHelper process becomes unresponsive or causes UE errors:
4747

4848
1. **Check Code Signing Configuration** (CRITICAL):
49+
4950
- Open the Xcode project: `mise run helper`
5051
- Navigate to: **taskbar.helper target** → **Signing & Capabilities** tab
5152
- Verify that a valid **Signing Certificate** is selected
@@ -54,6 +55,7 @@ If the TaskbarHelper process becomes unresponsive or causes UE errors:
5455
- Recommended: Use "Sign to Run Locally" or a valid development certificate
5556

5657
2. **Verify Entitlements**:
58+
5759
- Check that `taskbar.helper.entitlements` exists and has proper permissions
5860
- Required entitlements: Screen Recording, Accessibility
5961

@@ -68,6 +70,55 @@ If the TaskbarHelper process becomes unresponsive or causes UE errors:
6870

6971
- `mise run install-app` - Install built app to /Applications
7072

73+
## Browser-Based UI Testing
74+
75+
### Overview
76+
77+
開発サーバー(`mise run dev`)を起動すると、ブラウザから直接UIにアクセスしてテストできます。Electron APIのモックが自動的に注入され、実際のElectron環境と同じようにUIが動作します。
78+
79+
### アクセス方法
80+
81+
開発サーバー起動後、以下のURLにブラウザまたはPlaywright MCPでアクセス:
82+
83+
- **メインタスクバー**: http://localhost:10234/
84+
- **設定画面**: http://localhost:10234/option.html
85+
- **メニュー**: http://localhost:10234/menu.html
86+
- **全ウィンドウリスト**: http://localhost:10234/fullWindowList.html
87+
88+
### モック機能
89+
90+
- **自動イベント発火**: `Electron.send('windowReady')` が呼ばれると、自動的にサンプルデータが送信されます
91+
92+
- `process` - サンプルウィンドウデータ(TextEdit, Chrome, VS Code, Terminal)
93+
- `iconUpdate` - アイコンデータ
94+
- `displayInfo` - ディスプレイ情報
95+
- `updateOptions` - オプション設定
96+
97+
- **開発者ヘルパー**: ブラウザコンソールから `window.__mockHelpers` を使用して手動でイベントを発火できます
98+
99+
```javascript
100+
// 例: ウィンドウデータを更新
101+
__mockHelpers.updateWindows([...])
102+
103+
// 例: イベントを手動発火
104+
__mockHelpers.emit('process', __mockHelpers.sampleWindows)
105+
106+
// 例: windowReadyを再トリガー
107+
__mockHelpers.triggerWindowReady()
108+
```
109+
110+
### フィクスチャーのカスタマイズ
111+
112+
サンプルデータは `src/renderer/src/mocks/sample-fixture.ts` で定義されています。テストシナリオに合わせてカスタマイズ可能です。
113+
114+
### Playwright MCP による自動テスト
115+
116+
Playwright MCPを使用して、ブラウザ上でのUI動作を自動的にテストできます。モックが自動注入されるため、実際のElectron環境なしでUIの動作確認が可能です。
117+
118+
### 一時ファイルの保存先
119+
120+
**重要**: Playwright MCPで作業的にファイル(スクリーンショット、テストログなど)を作成する場合は、`.playwright-mcp/` ディレクトリを使用してください。このディレクトリは `.gitignore` に含まれており、リポジトリを汚しません。
121+
71122
## Architecture
72123

73124
### Main Process Structure

‎src/renderer/renderer-fullWindowList.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { createApp } from 'vue'
22
import App from './src/FullWindowList.vue'
33
import { routes } from 'vue-router/auto/routes'
44
import { createMemoryHistory, createRouter } from 'vue-router'
5+
import { injectElectronMocks } from './src/mocks/electron-mocks'
6+
7+
// ブラウザで開いた場合(Electron APIが存在しない場合)にモックを注入
8+
if (import.meta.env.DEV) {
9+
injectElectronMocks()
10+
}
11+
512
const router = createRouter({
613
history: createMemoryHistory(),
714
routes

‎src/renderer/renderer-main.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { createApp } from 'vue'
22
import App from './src/App.vue'
33
import { routes } from 'vue-router/auto/routes'
44
import { createRouter, createMemoryHistory } from 'vue-router'
5+
import { injectElectronMocks } from './src/mocks/electron-mocks'
6+
7+
// ブラウザで開いた場合(Electron APIが存在しない場合)にモックを注入
8+
if (import.meta.env.DEV) {
9+
injectElectronMocks()
10+
}
11+
512
const router = createRouter({
613
history: createMemoryHistory(),
714
routes: routes

‎src/renderer/renderer-menu.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { createApp } from 'vue'
22
import App from './src/Menu.vue'
33
import { routes } from 'vue-router/auto/routes'
44
import { createMemoryHistory, createRouter } from 'vue-router'
5+
import { injectElectronMocks } from './src/mocks/electron-mocks'
6+
7+
// ブラウザで開いた場合(Electron APIが存在しない場合)にモックを注入
8+
if (import.meta.env.DEV) {
9+
injectElectronMocks()
10+
}
11+
512
const router = createRouter({
613
history: createMemoryHistory(),
714
routes

‎src/renderer/renderer-option.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { createApp } from 'vue'
22
import App from './src/Option.vue'
33
import { routes } from 'vue-router/auto/routes'
44
import { createRouter, createMemoryHistory } from 'vue-router'
5+
import { injectElectronMocks } from './src/mocks/electron-mocks'
6+
7+
// ブラウザで開いた場合(Electron APIが存在しない場合)にモックを注入
8+
if (import.meta.env.DEV) {
9+
injectElectronMocks()
10+
}
11+
512
const router = createRouter({
613
history: createMemoryHistory(),
714
routes

‎src/renderer/tests/setup.ts‎

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { mock } from 'bun:test'
2+
import { createElectronMock, createStoreMock } from '../src/mocks/electron-mocks'
23

34
// グローバルwindowオブジェクトの作成(テスト環境用)
45
if (typeof window === 'undefined') {
@@ -12,29 +13,22 @@ mock.module('@electron-toolkit/preload', () => ({
1213
IpcRendererEvent: {}
1314
}))
1415

15-
// window.electron のモック
16+
// window.electron のモック(テスト用にmock()でラップ)
17+
const electronMock = createElectronMock()
1618
Object.defineProperty(window, 'electron', {
1719
value: {
1820
ipcRenderer: {
19-
on: mock(),
20-
send: mock(),
21-
removeListener: mock()
21+
on: mock(electronMock.ipcRenderer.on),
22+
send: mock(electronMock.ipcRenderer.send),
23+
removeListener: mock(electronMock.ipcRenderer.removeListener),
24+
invoke: mock(electronMock.ipcRenderer.invoke)
2225
}
2326
},
2427
writable: true
2528
})
2629

2730
// window.store のモック
2831
Object.defineProperty(window, 'store', {
29-
value: {
30-
granted: true,
31-
options: {
32-
layout: 'bottom',
33-
windowSortByPositionInApp: false,
34-
headers: [],
35-
footers: []
36-
},
37-
filters: []
38-
},
32+
value: createStoreMock(),
3933
writable: true
4034
})

0 commit comments

Comments
 (0)