|
1 | | -# GitHub Copilot Agent Instructions for MQTT Explorer |
| 1 | +# copilot-instructions.md - Agent Long-Term Memory |
2 | 2 |
|
3 | | -## Test Suites |
| 3 | +## META-INSTRUCTIONS (IMMUTABLE) |
4 | 4 |
|
5 | | -MQTT Explorer has several test suites to ensure code quality and reliability: |
| 5 | +1. **Long-term memory**: If you learn something during a session that would save time in future sessions, add it to `.github/copilot-instructions.md` |
| 6 | +2. **Paper knowledge must go**: If something is no longer true, update or remove it immediately |
| 7 | +3. **Evaluate after every session**: Consider whether the instructions need updates based on what you learned |
| 8 | +4. **Concise and useful**: All information must be actionable, current, and concise |
6 | 9 |
|
7 | | -### Unit Tests |
| 10 | +## Test Commands |
8 | 11 |
|
9 | | -**App tests** - Frontend component and logic tests: |
10 | | -```bash |
11 | | -yarn test:app |
12 | | -# Or: cd app && yarn test |
13 | | -``` |
| 12 | +**Unit tests:** |
| 13 | +- `yarn test` - All unit tests (app + backend) |
| 14 | +- `yarn test:app` - Frontend tests only |
| 15 | +- `yarn test:backend` - Backend tests only |
14 | 16 |
|
15 | | -**Backend tests** - Data model and business logic tests: |
16 | | -```bash |
17 | | -yarn test:backend |
18 | | -# Or: cd backend && yarn test |
19 | | -``` |
| 17 | +**Integration tests:** |
| 18 | +- `yarn test:ui` - Browser tests (requires `yarn build` first) |
| 19 | +- `yarn test:demo-video` - UI recording (requires Xvfb, mosquitto, tmux, ffmpeg) |
| 20 | +- `yarn test:mcp` - Model Context Protocol tests |
| 21 | +- `yarn test:all` - All tests (unit + demo-video) |
| 22 | +- `./scripts/runBrowserTests.sh` - Browser mode UI tests (requires mosquitto service) |
20 | 23 |
|
21 | | -**Run all unit tests**: |
22 | | -```bash |
23 | | -yarn test |
24 | | -``` |
| 24 | +**CI jobs:** `test`, `ui-tests`, `demo-video`, `test-browser`, `browser-ui-tests` |
25 | 25 |
|
26 | | -### Integration Tests |
| 26 | +**Important:** Browser UI tests require MQTT broker. In CI, GitHub Actions health checks ensure the mosquitto service is ready before tests run. |
27 | 27 |
|
28 | | -**UI test suite** - Independent, deterministic browser tests: |
29 | | -```bash |
30 | | -yarn test:ui |
31 | | -# Requires: yarn build |
32 | | -``` |
| 28 | +## Browser Mode |
33 | 29 |
|
34 | | -**Demo video generation** - UI test recording with video capture: |
35 | | -```bash |
36 | | -yarn test:demo-video |
37 | | -# Requires: Xvfb, mosquitto broker, tmux, ffmpeg |
38 | | -# For development: Use ./scripts/uiTests.sh for full video recording setup |
39 | | -``` |
| 30 | +**Prerequisites:** Node.js ≥24, Yarn, Mosquitto broker (for testing) |
40 | 31 |
|
41 | | -**MCP introspection tests** - Model Context Protocol tests: |
| 32 | +**Development (hot reload):** |
42 | 33 | ```bash |
43 | | -yarn test:mcp |
| 34 | +export MQTT_EXPLORER_USERNAME=admin MQTT_EXPLORER_PASSWORD=yourpass |
| 35 | +yarn dev:server |
| 36 | +# Backend: http://localhost:3000, Frontend: http://localhost:8080 (use this one) |
44 | 37 | ``` |
45 | 38 |
|
46 | | -**Run all tests** (unit + demo-video): |
| 39 | +**Production:** |
47 | 40 | ```bash |
48 | | -yarn test:all |
| 41 | +yarn build:server |
| 42 | +export MQTT_EXPLORER_USERNAME=admin MQTT_EXPLORER_PASSWORD=yourpass |
| 43 | +yarn start:server # http://localhost:3000 |
49 | 44 | ``` |
50 | 45 |
|
51 | | -### CI/CD Test Execution |
52 | | - |
53 | | -In CI environments, tests run in isolated containers with all dependencies pre-installed: |
54 | | -- `test` job: Runs unit tests (app + backend) |
55 | | -- `ui-tests` job: Runs UI test suite with screenshots |
56 | | -- `demo-video` job: Generates demo video with full recording setup |
57 | | -- `test-browser` job: Runs browser mode smoke tests |
| 46 | +**Build artifacts:** `dist/src/server.js`, `app/build/*.js`, `app/build/index.html` |
58 | 47 |
|
59 | 48 | ## Debugging Browser Mode |
60 | 49 |
|
61 | | -### Prerequisites |
62 | | -- Node.js 24 or higher |
63 | | -- Yarn package manager |
64 | | -- Running Mosquitto MQTT broker (for testing) |
65 | | - |
66 | | -### Development Mode (with Hot Reload) |
67 | | - |
68 | | -1. **Set credentials (required):** |
69 | | - ```bash |
70 | | - export MQTT_EXPLORER_USERNAME=admin |
71 | | - export MQTT_EXPLORER_PASSWORD=your_password |
72 | | - ``` |
73 | | - |
74 | | -2. **Start development servers:** |
75 | | - ```bash |
76 | | - yarn dev:server |
77 | | - ``` |
78 | | - This runs two servers in parallel: |
79 | | - - Backend server on http://localhost:3000 (serves API, WebSocket, authentication) |
80 | | - - Webpack dev server on http://localhost:8080 (serves frontend with hot reload) |
81 | | - |
82 | | -3. **Access the application:** |
83 | | - - Navigate to http://localhost:8080 (NOT :3000) |
84 | | - - Webpack dev server proxies API/WebSocket requests to backend on port 3000 |
85 | | - - Hot reload enabled - changes to React components update automatically |
86 | | - |
87 | | -### Production Mode (Production Build) |
88 | | - |
89 | | -1. **Build the browser version:** |
90 | | - ```bash |
91 | | - yarn build:server |
92 | | - ``` |
93 | | - This compiles TypeScript and builds the optimized webpack bundle |
| 50 | +**DevTools checks:** |
| 51 | +- Console: JavaScript errors, CSP errors (security headers), WebSocket issues |
| 52 | +- Network: Static asset loading, WebSocket status, API auth |
94 | 53 |
|
95 | | -2. **Start the server:** |
96 | | - ```bash |
97 | | - # Set credentials (required) - these are for the browser login page |
98 | | - export MQTT_EXPLORER_USERNAME=admin |
99 | | - export MQTT_EXPLORER_PASSWORD=your_password |
100 | | - |
101 | | - # Start server |
102 | | - yarn start:server |
103 | | - # OR: node dist/src/server.js |
104 | | - ``` |
105 | | - Server will run on http://localhost:3000 (serves both frontend and backend) |
| 54 | +**Common issues:** |
| 55 | +- **Blank page/CSP errors:** Add `'unsafe-eval'` to `scriptSrc` in `src/server.ts` helmet config |
| 56 | +- **Auth loop:** WebSocket auth failing - check Network → WS → Messages and server logs |
| 57 | +- **Theme errors:** Verify both ThemeProvider and LegacyThemeProvider in `app/src/index.tsx` |
106 | 58 |
|
107 | | -3. **Login to the application:** |
108 | | - - Navigate to http://localhost:3000 |
109 | | - - Enter the username and password you set in the environment variables |
110 | | - - Click "LOGIN" button |
111 | | - - After successful login, the main application will load |
112 | | - - The MQTT Connection modal will appear where you can configure broker connections |
113 | | - |
114 | | -### Debugging with Browser DevTools |
115 | | - |
116 | | -1. **Open browser DevTools:** |
117 | | - - Navigate to http://localhost:3000 |
118 | | - - Press F12 or right-click → Inspect |
119 | | - |
120 | | -2. **Check Console tab:** |
121 | | - - Look for JavaScript errors |
122 | | - - CSP (Content Security Policy) errors indicate security header issues |
123 | | - - Network errors indicate API/WebSocket connection issues |
124 | | - |
125 | | -3. **Check Network tab:** |
126 | | - - Verify static assets load correctly (JS bundles, CSS) |
127 | | - - Check WebSocket connection status |
128 | | - - Monitor API calls for authentication issues |
129 | | - |
130 | | -4. **Common Issues:** |
131 | | - |
132 | | - **Blank page / CSP errors:** |
133 | | - - Symptom: Console shows `EvalError: ... violates Content Security Policy` |
134 | | - - Cause: webpack runtime requires `unsafe-eval` for code splitting |
135 | | - - Fix: Add `'unsafe-eval'` to `scriptSrc` in `src/server.ts` helmet config |
136 | | - |
137 | | - **Authentication loop:** |
138 | | - - Symptom: Login dialog keeps reappearing |
139 | | - - Cause: WebSocket authentication failing |
140 | | - - Debug: Check browser Network tab → WS → Messages |
141 | | - - Check: Server logs for authentication errors |
142 | | - |
143 | | - **Theme errors:** |
144 | | - - Symptom: App loads but styling is broken |
145 | | - - Cause: Material-UI theme not loading correctly |
146 | | - - Check: Console for theme-related errors |
147 | | - - Verify: Both ThemeProvider and LegacyThemeProvider in `app/src/index.tsx` |
148 | | - |
149 | | - **Expected console warnings (non-fatal):** |
150 | | - - React 18 type warnings with Material-UI v5 components (dozens of "Failed prop type" warnings) |
151 | | - - `TypeError: Cannot read properties of undefined (reading 'on')` from IpcRendererEventBus - this is expected in browser mode as there's no Electron IPC |
152 | | - - MUI locale warnings for `en-US` - expected, app uses available locales |
153 | | - - `componentWillReceiveProps` deprecation warnings - from legacy TreeComponent |
154 | | - - ACE editor autocomplete warnings - expected, features not imported |
155 | | - - CSP worker violation for ACE editor - known issue, editor still functions |
156 | | - |
157 | | - These warnings don't prevent the application from functioning correctly. |
158 | | - |
159 | | -### Using Playwright for Automated Testing |
| 59 | +**Expected warnings (non-fatal):** |
| 60 | +- React 18 + Material-UI v5 type warnings |
| 61 | +- IpcRendererEventBus errors (no Electron IPC in browser mode) |
| 62 | +- MUI locale, componentWillReceiveProps, ACE editor warnings |
160 | 63 |
|
| 64 | +**WebSocket debugging:** |
161 | 65 | ```bash |
162 | | -# Start server in background |
163 | | -export MQTT_EXPLORER_USERNAME=admin |
164 | | -export MQTT_EXPLORER_PASSWORD=test123 |
165 | | -node dist/src/server.js & |
166 | | - |
167 | | -# Use Playwright browser tool (in Copilot agent context) |
168 | | -playwright-browser_navigate http://localhost:3000 |
169 | | -playwright-browser_take_screenshot --filename debug.png |
170 | | -playwright-browser_console_messages # Check for errors |
| 66 | +node dist/src/server.js 2>&1 | tee server.log |
| 67 | +# Check DevTools → Network → WS → Messages for handshake |
| 68 | +# CORS: check ALLOWED_ORIGINS env var |
171 | 69 | ``` |
172 | 70 |
|
173 | | -### Expected UI Flow |
| 71 | +**Security notes:** |
| 72 | +- `unsafe-eval` in CSP required for webpack (security tradeoff) |
| 73 | +- Never hardcode credentials (use env vars) |
| 74 | +- Production: use HTTPS with reverse proxy |
| 75 | +- Rate limit: 5 auth attempts/15min/IP |
| 76 | +- File upload limit: 16MB |
174 | 77 |
|
175 | | -1. **Login Page** (https://github.com/user-attachments/assets/383305e1-2169-433c-a668-5a05da0c343a) |
176 | | - - Enter username and password from environment variables |
177 | | - - Click "LOGIN" button |
178 | | - |
179 | | -2. **Main Application After Login** (https://github.com/user-attachments/assets/cc4d665f-2665-4289-b2fc-dc4986f9ab5b) |
180 | | - - Application loads with sidebar, topic tree, value panel, and publish panel |
181 | | - - MQTT Connection modal appears automatically for first-time setup |
182 | | - - Configure broker connection (host, port, credentials, etc.) |
183 | | - - Click "CONNECT" to establish MQTT connection |
184 | | - |
185 | | -3. **Application Features:** |
186 | | - - Topic tree on the left shows MQTT topic hierarchy |
187 | | - - Value panel shows selected topic's message content |
188 | | - - Publish panel allows sending MQTT messages |
189 | | - - Charts panel for numeric value visualization |
190 | | - - Settings drawer for app configuration |
| 78 | +**Key files:** |
| 79 | +- `src/server.ts` - Express server, security middleware |
| 80 | +- `app/webpack.browser.config.mjs` - Browser webpack config |
| 81 | +- `app/src/browserEventBus.ts` - Socket.io client |
| 82 | +- `app/src/components/BrowserAuthWrapper.tsx` - Auth dialog |
| 83 | +- `app/src/index.tsx` - React entry, theme providers |
191 | 84 |
|
192 | | -### Debugging WebSocket Connection |
| 85 | +## Styling Conventions |
193 | 86 |
|
194 | | -1. **Check server logs:** |
195 | | - ```bash |
196 | | - node dist/src/server.js 2>&1 | tee server.log |
197 | | - ``` |
| 87 | +When modifying or creating UI components, follow the styling patterns documented in <a>STYLING.md</a>. |
198 | 88 |
|
199 | | -2. **Check browser WebSocket:** |
200 | | - - DevTools → Network → WS tab |
201 | | - - Look for socket.io connection |
202 | | - - Check Messages tab for authentication handshake |
| 89 | +**Key points for AI agents:** |
| 90 | +- Use Material-UI (MUI) v7 components with `withStyles` HOC for styling |
| 91 | +- Access theme colors via `theme.palette.*`, spacing via `theme.spacing()`, typography via `theme.typography.*` |
| 92 | +- Support both light and dark modes with theme-conditional styling |
| 93 | +- Import Material-UI colors: `import { blueGrey, amber, green, red } from '@mui/material/colors'` |
203 | 94 |
|
204 | | -3. **Common WebSocket issues:** |
205 | | - - CORS errors: Check `ALLOWED_ORIGINS` environment variable |
206 | | - - Authentication errors: Verify credentials in sessionStorage |
207 | | - - Connection refused: Server not running or port blocked |
| 95 | +## Mobile Testing Workflow |
208 | 96 |
|
209 | | -### Development vs Production |
210 | | - |
211 | | -**Development mode:** |
| 97 | +**Prerequisites for mobile testing:** |
212 | 98 | ```bash |
213 | | -yarn dev:server |
214 | | -# Runs webpack-dev-server with hot reload |
215 | | -# More verbose error messages |
216 | | -# Source maps enabled |
217 | | -``` |
| 99 | +# Install Playwright browsers |
| 100 | +npx playwright install --with-deps chromium |
218 | 101 |
|
219 | | -**Production mode:** |
220 | | -```bash |
221 | | -NODE_ENV=production yarn build:server |
222 | | -NODE_ENV=production node dist/src/server.js |
223 | | -# Minified bundles |
224 | | -# Generic error messages (security) |
225 | | -# HSTS enabled |
| 102 | +# Configure mosquitto to allow anonymous connections (for local testing) |
| 103 | +echo "listener 1883 |
| 104 | +allow_anonymous true" | sudo tee /etc/mosquitto/conf.d/allow-anonymous.conf |
| 105 | +sudo systemctl restart mosquitto |
226 | 106 | ``` |
227 | 107 |
|
228 | | -### Build Artifacts |
229 | | - |
230 | | -After `yarn build:server`, check: |
231 | | -- `dist/src/server.js` - Compiled server code |
232 | | -- `app/build/*.js` - Webpack bundles |
233 | | -- `app/build/index.html` - Entry point HTML |
234 | | - |
235 | | -### Troubleshooting Checklist |
| 108 | +**Interactive testing with mobile viewport:** |
| 109 | +```bash |
| 110 | +# Set up environment |
| 111 | +export MQTT_EXPLORER_SKIP_AUTH=true |
| 112 | +export MQTT_AUTO_CONNECT_HOST=127.0.0.1 |
236 | 113 |
|
237 | | -- [ ] Node.js version >=24 |
238 | | -- [ ] `yarn install` completed without errors |
239 | | -- [ ] TypeScript compilation successful (`npx tsc`) |
240 | | -- [ ] Webpack build successful (check `app/build/` directory) |
241 | | -- [ ] Server starts without errors |
242 | | -- [ ] Can access http://localhost:3000 |
243 | | -- [ ] Login dialog appears |
244 | | -- [ ] No CSP errors in console |
245 | | -- [ ] WebSocket connects successfully |
246 | | -- [ ] App renders after login |
| 114 | +# Build and start server |
| 115 | +yarn build:server |
| 116 | +node dist/src/server.js |
247 | 117 |
|
248 | | -### Security Considerations |
| 118 | +# In another terminal, run Playwright test with mobile viewport |
| 119 | +# Create test script with viewport: { width: 412, height: 914 } |
| 120 | +# Always INSPECT the rendered output, don't rely on assumptions |
| 121 | +``` |
249 | 122 |
|
250 | | -When debugging, be aware that: |
251 | | -- `unsafe-eval` in CSP is required for webpack but reduces security |
252 | | -- Credentials should never be hardcoded (use environment variables) |
253 | | -- In production, use HTTPS with a reverse proxy (nginx/Apache) |
254 | | -- Rate limiting is active (5 auth attempts per 15 min per IP) |
255 | | -- File upload size limit is 16MB |
| 123 | +**Key lesson**: Mobile tree visibility issues often stem from: |
| 124 | +1. CSS flex/absolute positioning conflicts |
| 125 | +2. Missing Redux state updates (connection not propagated to frontend) |
| 126 | +3. MQTT broker authentication (mosquitto requires `allow_anonymous true` for testing) |
| 127 | +4. Timing issues (frontend subscribing to events after backend emits them) |
256 | 128 |
|
257 | | -### Related Files |
| 129 | +**Server-side auto-connect** (for testing): |
| 130 | +```bash |
| 131 | +export MQTT_AUTO_CONNECT_HOST=127.0.0.1 |
| 132 | +export MQTT_AUTO_CONNECT_PORT=1883 # optional |
| 133 | +export MQTT_AUTO_CONNECT_PROTOCOL=mqtt # optional |
| 134 | +``` |
258 | 135 |
|
259 | | -- `src/server.ts` - Express server with security middleware |
260 | | -- `app/webpack.browser.config.mjs` - Browser-specific webpack config |
261 | | -- `app/src/browserEventBus.ts` - Socket.io client for browser mode |
262 | | -- `app/src/components/BrowserAuthWrapper.tsx` - Authentication dialog |
263 | | -- `app/src/index.tsx` - React app entry point with theme providers |
0 commit comments