test(hooks): harden cross-platform MCP coverage

- replace the Windows-brittle chmod read-error setup with a directory-based failure case

- force the browser installed-copy regression through the non-global WebSocket path
This commit is contained in:
Tam Nhu Tran
2026-04-13 13:10:05 -04:00
parent d30f5803a7
commit 3103f3f293
2 changed files with 14 additions and 17 deletions
+4 -8
View File
@@ -871,12 +871,10 @@ describe('Image Analyzer Hook', () => {
});
it('should output valid JSON structure on file read error', async () => {
// Create and immediately delete file to trigger error
// Use a directory with an analyzable extension so readFileSync fails
// consistently across POSIX and Windows.
const errorPath = path.join(TEST_DIR, 'error-test.png');
createTestPng(errorPath);
// Make file unreadable (simulate permission error)
fs.chmodSync(errorPath, 0o000);
fs.mkdirSync(errorPath);
const result = await invokeHookAsync(
{
@@ -886,9 +884,7 @@ describe('Image Analyzer Hook', () => {
{ CCS_IMAGE_ANALYSIS_ENABLED: '1', CCS_PROFILE_TYPE: 'cliproxy' }
);
// Restore permissions and cleanup
fs.chmodSync(errorPath, 0o644);
fs.unlinkSync(errorPath);
fs.rmSync(errorPath, { recursive: true, force: true });
// Should output error in JSON format
expect(result.code).toBe(2);
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it } from 'bun:test';
import { spawn } from 'child_process';
import { cpSync, mkdirSync, mkdtempSync, rmSync } from 'node:fs';
import { cpSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import * as http from 'node:http';
import { WebSocketServer } from 'ws';
import { tmpdir } from 'node:os';
@@ -522,17 +522,18 @@ describe('ccs-browser MCP server', () => {
}
});
it('works from an installed copy when ws is absent but undici is available via NODE_PATH', async () => {
it('works from an installed copy when global WebSocket is unavailable and NODE_PATH supplies package dependencies', async () => {
const installDir = mkdtempSync(join(tmpdir(), 'ccs-browser-installed-copy-'));
const installedServerPath = join(installDir, 'ccs-browser-server.cjs');
const nodeModulesDir = join(installDir, 'node_modules');
const bootstrapServerPath = join(installDir, 'bootstrap.cjs');
try {
cpSync(bundledServerPath, installedServerPath);
mkdirSync(nodeModulesDir, { recursive: true });
cpSync(join(process.cwd(), 'node_modules', 'undici'), join(nodeModulesDir, 'undici'), {
recursive: true,
});
writeFileSync(
bootstrapServerPath,
'delete globalThis.WebSocket;\nrequire("./ccs-browser-server.cjs");\n',
'utf8'
);
const responses = await runMcpRequests(
[{ id: 'page-1', title: 'Installed Copy', currentUrl: 'https://example.com/' }],
@@ -545,9 +546,9 @@ describe('ccs-browser MCP server', () => {
},
],
{
serverPath: installedServerPath,
serverPath: bootstrapServerPath,
childEnv: {
NODE_PATH: nodeModulesDir,
NODE_PATH: join(process.cwd(), 'node_modules'),
},
}
);