Files
TrueGrowth/specs/005-declarative-tracking/VERIFICATION_GUIDE.md

6.7 KiB
Raw Permalink Blame History

重复事件上报修复 - 验证指南

修复版本: V2 修复日期: 2025-12-05

快速验证步骤

方法 1: 浏览器控制台检查 推荐

  1. 打开应用的浏览器控制台F12

  2. 运行以下代码检查事件监听器数量:

// 检查 click 事件监听器
const listeners = getEventListeners(document.body);
console.log('📊 Click listeners count:', listeners.click?.length);

// 预期输出: 1
// 如果 > 1说明还有重复问题
  1. 结果判断:
    • listeners.click.length === 1 → 修复成功
    • listeners.click.length > 1 → 仍有问题,请重启应用

方法 2: 启用调试日志

  1. 找到 packages/drawnix/src/drawnix.tsx 文件

  2. 修改 plugins 配置,启用 devMode:

const plugins: PlaitPlugin[] = [
  withDraw,
  withGroup,
  withMind,
  withMindExtend,
  withCommonPlugin,
  buildDrawnixHotkeyPlugin(updateAppState),
  withFreehand,
  buildPencilPlugin(updateAppState),
  buildTextLinkPlugin(updateAppState),
  withVideo,
  // ⬇️ 修改这一行,添加配置
  (editor) => withTracking(editor, {
    devMode: true,      // 启用调试模式
    logLevel: 'debug'   // 显示详细日志
  }),
];
  1. 刷新应用,点击任意按钮

  2. 观察控制台输出:

✅ 正常情况(修复成功):
[Tracking] ✅ Track: chat_click_drawer_close

❌ 异常情况(仍有重复):
[Tracking] ✅ Track: chat_click_drawer_close
[Tracking] ✅ Track: chat_click_drawer_close  ⬅️ 重复了!

方法 3: Umami Analytics 后台验证

  1. 登录 Umami Analytics 后台

  2. 进入"实时"Real-time视图

  3. 在应用中点击一个按钮(如"收起对话"

  4. 观察 Umami 后台的事件流:

✅ 正常情况:
12:34:56  chat_click_drawer_close  (1 次)

❌ 异常情况:
12:34:56  chat_click_drawer_close  (2 次) ⬅️ 重复了!
12:34:56  chat_click_drawer_close

高级验证

验证单例模式

在控制台运行:

// 检查是否是单例
let service1, service2;

// 模拟创建多个 editor
const editor1 = { /* mock editor */ };
const editor2 = { /* mock editor */ };

// 应该共享同一个 trackingService 实例
console.log(editor1.trackingService === editor2.trackingService);
// 预期输出: true

验证防抖机制

  1. 启用 devMode参考方法2

  2. 快速双击任意按钮(<200ms 间隔)

  3. 观察控制台输出:

[Tracking] ✅ Track: toolbar_click_hand
[Tracking] 🚫 Global debounce: toolbar_click_hand (85ms ago)  ⬅️ 第二次被拦截
  1. 正常点击>200ms 间隔)
[Tracking] ✅ Track: toolbar_click_hand
// ... 等待 300ms ...
[Tracking] ✅ Track: toolbar_click_hand  ⬅️ 第二次正常上报

验证 onClick 功能

点击各个按钮,确认功能正常:

  • 聊天抽屉触发器:能正常打开/关闭对话框
  • 工具栏按钮:能正常切换工具
  • 任务队列按钮:能正常删除/重试任务
  • 设置按钮:能正常保存设置

常见问题排查

问题1: 仍然有重复上报

可能原因: 应用未重启,旧的 TrackingService 实例仍在内存中

解决方法:

  1. 完全关闭浏览器标签页
  2. 重新打开应用
  3. 硬刷新Ctrl + Shift + R 或 Cmd + Shift + R

问题2: 监听器数量 > 1

可能原因: 热重载导致多个实例累积

解决方法:

// 在控制台手动重置
import { resetGlobalTrackingService } from './plugins/tracking';
resetGlobalTrackingService();
location.reload();

问题3: onClick 不工作

可能原因: 事件被其他代码阻止

检查步骤:

  1. 打开控制台 → Elements 标签
  2. 选中按钮元素
  3. 查看 Event Listeners
  4. 确认 click 事件监听器存在

问题4: 调试日志不显示

可能原因: devMode 未启用或配置未生效

检查步骤:

// 在控制台检查配置
const service = document.querySelector('.drawnix')?.__trackingService;
console.log('DevMode:', service?.config?.devMode);
// 预期输出: true

性能验证

检查内存泄漏

  1. 打开 Chrome DevTools → Performance 标签
  2. 开始录制
  3. 在应用中进行正常操作(点击按钮、打开对话框等)
  4. 停止录制
  5. 查看内存使用曲线

正常情况: 内存曲线平稳,有小幅波动但无持续增长

检查事件处理时间

// 在控制台测试点击响应时间
console.time('click-response');
document.querySelector('[data-track="chat_click_drawer_close"]').click();
console.timeEnd('click-response');
// 预期输出: < 5ms

回归测试清单

验证以下功能是否正常:

聊天功能

  • 打开/关闭聊天抽屉
  • 切换会话列表
  • 新建会话
  • 删除会话
  • 选择模型

工具栏功能

  • 切换工具(手型、选择、画笔等)
  • 调整尺寸
  • 选择颜色
  • 缩放画布

任务队列功能

  • 打开/关闭任务面板
  • 预览任务结果
  • 删除任务
  • 重试失败任务
  • 插入到画板
  • 下载结果

AI 生成功能

  • 图片生成
  • 视频生成
  • 调整参数
  • 插入到画板

设置功能

  • 打开设置对话框
  • 保存设置
  • 取消设置

验证成功标准

所有以下条件都满足,说明修复成功:

  1. 事件监听器数量 = 1
  2. 每次点击只上报 1 次事件
  3. onClick 功能全部正常
  4. 防抖机制正常工作(快速双击只上报 1 次)
  5. devMode 日志正常显示
  6. 无内存泄漏
  7. 响应时间 < 5ms

报告问题

如果验证失败,请提供以下信息:

  1. 监听器数量: getEventListeners(document.body).click?.length
  2. 控制台截图: 包含错误或异常日志
  3. Umami 截图: 显示重复事件
  4. 复现步骤: 详细的操作步骤
  5. 环境信息:
    • 浏览器版本
    • 操作系统
    • 应用版本/分支

自动化测试(可选)

创建 Cypress/Playwright 测试:

describe('Tracking Deduplication', () => {
  it('should track event only once', () => {
    // 清空 Umami 事件队列
    cy.window().then((win) => {
      win.localStorage.removeItem('umami.cache');
    });

    // 点击按钮
    cy.get('[data-track="chat_click_drawer_close"]').click();

    // 等待上报
    cy.wait(1000);

    // 验证只上报了 1 次
    cy.window().then((win) => {
      const events = JSON.parse(win.localStorage.getItem('umami.cache') || '[]');
      const clickEvents = events.filter(e => e.name === 'chat_click_drawer_close');
      expect(clickEvents).to.have.length(1);
    });
  });
});

最后更新: 2025-12-05 文档版本: V2 适用修复: BUG_FIX_DUPLICATE_EVENTS_V2.md