Files
weixin-plugin-test/scripts/test-weixin-simple.js
zyh 77019ec050 feat: 初始化微信插件独立测试环境
添加完整的微信插件测试框架,包含:
- 微信插件源码(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>
2026-03-30 07:14:00 +00:00

297 lines
8.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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);
});