Skip to content

Commit 5adf3fb

Browse files
committed
ci: add smoke test to catch MockBrowserWindow regressions
Enhanced smoke-test.sh to exercise IPC and WebSocket flows that use MockBrowserWindow methods like isDestroyed(). Added smoke-test job to CI that runs on merge queue. The test: - Creates a project via IPC - Creates a workspace via IPC (triggers isDestroyed checks) - Subscribes to workspace chat via WebSocket This would have caught the regression in commit 3ca9c7e where isDestroyed() was added to ipcMain.ts but not to MockBrowserWindow in src/cli/server.ts. _Generated with mux_
1 parent 35ad55b commit 5adf3fb

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

.github/workflows/ci.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,44 @@ jobs:
238238
if: always()
239239
run: docker rm -f mux-test || true
240240

241+
npm-smoke-test:
242+
name: NPM Smoke Test
243+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
244+
# Only run on merge queue - tests IPC/WebSocket flows that catch MockBrowserWindow bugs
245+
if: github.event_name == 'merge_group'
246+
steps:
247+
- name: Checkout code
248+
uses: actions/checkout@v4
249+
with:
250+
fetch-depth: 0 # Required for git describe to find tags
251+
252+
- uses: ./.github/actions/setup-mux
253+
254+
- name: Build application
255+
run: make build
256+
257+
- name: Pack npm package
258+
run: npm pack
259+
260+
- name: Run smoke test
261+
env:
262+
SERVER_PORT: 3001
263+
SERVER_HOST: localhost
264+
STARTUP_TIMEOUT: 30
265+
run: |
266+
# Find the actual tarball name (version may vary)
267+
TARBALL=$(ls mux-*.tgz | head -1)
268+
PACKAGE_TARBALL="$TARBALL" ./scripts/smoke-test.sh
269+
270+
- name: Upload server logs on failure
271+
if: failure()
272+
uses: actions/upload-artifact@v4
273+
with:
274+
name: npm-smoke-test-logs
275+
path: /tmp/tmp.*/server.log
276+
if-no-files-found: warn
277+
retention-days: 7
278+
241279
check-codex-comments:
242280
name: Check Codex Comments
243281
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}

scripts/smoke-test.sh

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,120 @@ fi
172172

173173
log_info "✅ Root endpoint is accessible"
174174

175+
# Test IPC functionality - this exercises MockBrowserWindow methods like isDestroyed()
176+
log_info "Testing IPC project creation..."
177+
178+
# Create a temporary git repo for the test project
179+
PROJECT_DIR=$(mktemp -d)
180+
git init -b main "$PROJECT_DIR" >/dev/null 2>&1
181+
git -C "$PROJECT_DIR" config user.email "test@example.com"
182+
git -C "$PROJECT_DIR" config user.name "Test User"
183+
touch "$PROJECT_DIR/README.md"
184+
git -C "$PROJECT_DIR" add .
185+
git -C "$PROJECT_DIR" commit -m "Initial commit" >/dev/null 2>&1
186+
187+
# Create project via IPC
188+
PROJECT_RESPONSE=$(curl -sf -X POST "http://${SERVER_HOST}:${SERVER_PORT}/ipc/project%3Acreate" \
189+
-H "Content-Type: application/json" \
190+
-d "{\"args\": [\"$PROJECT_DIR\"]}" || true)
191+
192+
if [[ -z "$PROJECT_RESPONSE" ]]; then
193+
log_error "Project creation returned empty response"
194+
rm -rf "$PROJECT_DIR"
195+
exit 1
196+
fi
197+
198+
if ! echo "$PROJECT_RESPONSE" | jq -e '.success == true' >/dev/null 2>&1; then
199+
log_error "Project creation failed: $PROJECT_RESPONSE"
200+
rm -rf "$PROJECT_DIR"
201+
exit 1
202+
fi
203+
204+
log_info "✅ Project created via IPC"
205+
206+
# Create workspace via IPC - this exercises more of the IPC layer
207+
log_info "Testing IPC workspace creation..."
208+
WORKSPACE_RESPONSE=$(curl -sf -X POST "http://${SERVER_HOST}:${SERVER_PORT}/ipc/workspace%3Acreate" \
209+
-H "Content-Type: application/json" \
210+
-d "{\"args\": [\"$PROJECT_DIR\", \"smoke-test-branch\", \"main\"]}" || true)
211+
212+
if [[ -z "$WORKSPACE_RESPONSE" ]]; then
213+
log_error "Workspace creation returned empty response"
214+
rm -rf "$PROJECT_DIR"
215+
exit 1
216+
fi
217+
218+
if ! echo "$WORKSPACE_RESPONSE" | jq -e '.success == true' >/dev/null 2>&1; then
219+
log_error "Workspace creation failed: $WORKSPACE_RESPONSE"
220+
rm -rf "$PROJECT_DIR"
221+
exit 1
222+
fi
223+
224+
WORKSPACE_ID=$(echo "$WORKSPACE_RESPONSE" | jq -r '.data.metadata.id // .data.id // empty')
225+
if [[ -z "$WORKSPACE_ID" ]]; then
226+
log_error "Workspace ID not returned from creation"
227+
rm -rf "$PROJECT_DIR"
228+
exit 1
229+
fi
230+
231+
log_info "✅ Workspace created via IPC (id: $WORKSPACE_ID)"
232+
233+
# Test WebSocket subscription - this triggers MockBrowserWindow.isDestroyed() checks
234+
# The chat subscription triggers getOrCreateSession() which registers event handlers
235+
# that call isDestroyed() before sending messages
236+
log_info "Testing WebSocket chat subscription..."
237+
238+
# Use Node.js to test WebSocket since it's guaranteed to be available
239+
node -e "
240+
const WebSocket = require('ws');
241+
const ws = new WebSocket('ws://${SERVER_HOST}:${SERVER_PORT}/ws');
242+
243+
const timeout = setTimeout(() => {
244+
console.log('WebSocket test timed out (expected - no messages to replay)');
245+
ws.close();
246+
process.exit(0);
247+
}, 3000);
248+
249+
ws.on('open', () => {
250+
// Subscribe to workspace chat - this triggers session creation and isDestroyed() checks
251+
ws.send(JSON.stringify({
252+
type: 'subscribe',
253+
channel: 'workspace:chat',
254+
workspaceId: '${WORKSPACE_ID}'
255+
}));
256+
257+
// Also subscribe to metadata to exercise that code path
258+
ws.send(JSON.stringify({
259+
type: 'subscribe',
260+
channel: 'workspace:metadata'
261+
}));
262+
});
263+
264+
ws.on('message', (data) => {
265+
console.log('Received WebSocket message');
266+
clearTimeout(timeout);
267+
ws.close();
268+
process.exit(0);
269+
});
270+
271+
ws.on('error', (err) => {
272+
console.error('WebSocket error:', err.message);
273+
clearTimeout(timeout);
274+
process.exit(1);
275+
});
276+
" 2>&1
277+
278+
WS_EXIT_CODE=$?
279+
if [[ $WS_EXIT_CODE -ne 0 ]]; then
280+
log_error "WebSocket subscription test failed"
281+
rm -rf "$PROJECT_DIR"
282+
exit 1
283+
fi
284+
285+
log_info "✅ WebSocket subscription completed without errors"
286+
287+
# Cleanup test project
288+
rm -rf "$PROJECT_DIR"
289+
175290
# All tests passed
176291
log_info "🎉 All smoke tests passed!"

0 commit comments

Comments
 (0)