#!/usr/bin/env node /** * 微信插件简化测试脚本 * * 这是一个最小化的测试脚本,用于验证微信插件的基本功能: * 1. 检查依赖和模块加载 * 2. 二维码登录 * 3. 消息收发 * * 使用方法: * node scripts/test-weixin-simple.js * 或 * npm run test:simple */ import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const projectRoot = path.resolve(__dirname, '..'); const weixinPluginPath = path.join(projectRoot, 'weixin-plugin'); console.log('微信插件简化测试'); console.log('='.repeat(50)); // ============================================================================= // 依赖检查 // ============================================================================= async function checkDependencies() { console.log('\n1. 检查依赖...'); const dependencies = [ { name: 'qrcode', import: () => import('qrcode') }, { name: 'fs', import: () => import('fs') }, { name: 'path', import: () => import('path') }, { name: 'crypto', import: () => import('crypto') }, { name: 'os', import: () => import('os') }, ]; const missing = []; for (const dep of dependencies) { try { await dep.import(); console.log(` ✓ ${dep.name}`); } catch { console.log(` ✗ ${dep.name} (缺失)`); missing.push(dep.name); } } if (missing.length > 0) { console.log(`\n请安装缺失的依赖: npm install ${missing.join(' ')}`); process.exit(1); } console.log(' 所有依赖检查通过\n'); } // ============================================================================= // 模块路径解析 // ============================================================================= function resolveModulePath() { // 优先使用编译后的 dist 目录 const distPath = path.join(weixinPluginPath, 'dist', 'weixinGateway.js'); if (fs.existsSync(distPath)) { console.log('\n使用编译后的模块:', distPath); return distPath; } // 回退到 TypeScript 源文件(需要 tsx 或类似工具) const srcPath = path.join(weixinPluginPath, 'weixinGateway.ts'); if (fs.existsSync(srcPath)) { console.log('\n注意: 发现 TypeScript 源文件'); console.log(' 建议: 先运行编译脚本'); console.log(' npm run build\n'); return srcPath; } throw new Error('找不到 weixinGateway 模块文件'); } // ============================================================================= // 模块加载测试 // ============================================================================= async function testModuleLoading() { console.log('2. 测试模块加载...'); try { const modulePath = resolveModulePath(); console.log(` 加载路径: ${modulePath}`); const module = await import(modulePath); console.log(` ✓ WeixinGateway: ${typeof module.WeixinGateway}`); console.log(` ✓ startWeixinLogin: ${typeof module.startWeixinLogin}`); console.log(` ✓ waitWeixinLogin: ${typeof module.waitWeixinLogin}`); console.log(' 模块加载成功\n'); return module; } catch (err) { console.log(` ✗ 加载失败: ${err.message}`); console.log('\n可能的原因:'); console.log(' 1. TypeScript 文件需要先编译'); console.log(' 解决方案: npm run build'); console.log(' 2. 缺少 weixin-plugin/types.ts 文件'); console.log(' 解决方案: 检查文件是否存在'); console.log(' 3. 需要安装 tsx 来运行 TypeScript'); console.log(' 解决方案: npm install -g tsx\n'); // 尝试提供更详细的错误信息 if (err.message.includes('Cannot find module')) { console.log('详细错误: 模块未找到'); console.log('请确保已编译微信插件:'); console.log(' npm run build\n'); } throw err; } } // ============================================================================= // 二维码登录测试 // ============================================================================= async function testQRLogin(module) { console.log('3. 测试二维码登录...'); const { startWeixinLogin, waitWeixinLogin } = module; console.log(' 正在获取二维码...'); try { const { sessionKey, qrcodeUrl } = await startWeixinLogin('test-account'); if (!qrcodeUrl) { throw new Error('未能获取二维码'); } // 保存二维码 const matches = qrcodeUrl.match(/^data:image\/png;base64,(.+)$/); if (matches) { const buffer = Buffer.from(matches[1], 'base64'); const qrcodePath = path.join(projectRoot, 'weixin-qrcode.png'); fs.writeFileSync(qrcodePath, buffer); console.log(` ✓ 二维码已保存到: ${qrcodePath}`); } console.log(' ✓ 二维码获取成功'); console.log(` Session Key: ${sessionKey}`); console.log('\n请使用微信扫描二维码登录'); console.log('等待登录(最长 5 分钟)...\n'); // 等待登录 const result = await waitWeixinLogin(sessionKey, 5 * 60 * 1000); if (!result.connected) { throw new Error(result.error || '登录失败'); } console.log(' ✓ 登录成功!'); console.log(` Account ID: ${result.accountId}`); console.log(` User ID: ${result.userId}`); console.log(` Base URL: ${result.baseUrl}\n`); return result; } catch (err) { console.log(` ✗ 登录失败: ${err.message}\n`); throw err; } } // ============================================================================= // 网关启动测试 // ============================================================================= async function testGateway(module) { console.log('4. 测试网关启动...'); const { WeixinGateway } = module; try { const gateway = new WeixinGateway(); // 监听事件 let connected = false; let hasError = false; gateway.once('connected', () => { connected = true; console.log(' ✓ 网关已连接'); }); gateway.once('error', (err) => { hasError = true; console.log(` ✗ 网关错误: ${err.message}`); }); // 启动网关 await gateway.start({ enabled: true, debug: true }); // 等待连接 await new Promise((resolve, reject) => { const timeout = setTimeout(() => { if (!connected) { reject(new Error('连接超时')); } else { resolve(); } }, 10000); gateway.once('connected', () => { clearTimeout(timeout); resolve(); }); gateway.once('error', (err) => { clearTimeout(timeout); reject(err); }); }); if (hasError) { throw new Error('网关启动时发生错误'); } // 检查状态 const status = gateway.getStatus(); console.log(` 连接状态: ${status.connected ? '已连接' : '未连接'}`); console.log(` 账号ID: ${status.accountId}`); console.log(` 启动时间: ${status.startedAt ? new Date(status.startedAt).toLocaleString() : 'N/A'}\n`); // 停止网关 await gateway.stop(); console.log(' ✓ 网关已停止\n'); return true; } catch (err) { console.log(` ✗ 网关测试失败: ${err.message}\n`); throw err; } } // ============================================================================= // 主流程 // ============================================================================= async function main() { const startTime = Date.now(); try { // 1. 检查依赖 await checkDependencies(); // 2. 测试模块加载 const module = await testModuleLoading(); // 3. 测试二维码登录 await testQRLogin(module); // 4. 测试网关 await testGateway(module); // 完成 const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); console.log('='.repeat(50)); console.log(`✓ 所有测试通过!耗时 ${elapsed} 秒`); console.log('\n微信插件基本功能验证通过,可以正常使用。'); console.log('如需完整测试(包括消息收发),请运行:'); console.log(' npm run test:full\n'); } catch (err) { console.log('='.repeat(50)); console.log('✗ 测试失败'); console.log(`错误: ${err.message}\n`); if (err.stack) { console.log('详细错误信息:'); console.log(err.stack); } process.exit(1); } } // 执行 main().catch((err) => { console.error('未处理的错误:', err); process.exit(1); });