添加完整的微信插件测试框架,包含: - 微信插件源码(weixin-plugin/) - TypeScript 类型定义(types.ts) - 插件编译脚本(scripts/build-weixin-plugin.sh) - 简化测试脚本(scripts/test-weixin-simple.js) - 完整测试脚本(scripts/test-weixin-plugin.js) - 项目配置和依赖管理(package.json) - 使用说明文档(README.md) 主要功能: - 支持二维码登录认证 - HTTP 长轮询消息接收 - 文本、图片、视频、文件消息收发 - 自动回复测试 - 运行状态统计 Generated with [Claude Code](https://claude.com/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
297 lines
8.4 KiB
JavaScript
297 lines
8.4 KiB
JavaScript
#!/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);
|
||
});
|