feat: enhance web extension with export functionality and utility improvements
Some checks failed
Tests / Tests (push) Has been cancelled
ESLint Check / ESLint Check and Report Upload (push) Has been cancelled
Prettier Check / Format Check (push) Has been cancelled
Prettier Check / Format Code (push) Has been cancelled
ESLint Check / Build Base for Bundle Size Comparison (push) Has been cancelled

- Add export functionality to SessionList and Player pages
- Add new utility modules: dataOperations, format, path, settings
- Update manifest with export and download permissions
- Enhance storage utility with new data operations
- Add various test scripts and documentation files
This commit is contained in:
xugp
2026-04-16 10:15:10 +08:00
parent 2a7084db5b
commit 71438691b3
38 changed files with 11241 additions and 2338 deletions

157
button-binding-test.js Normal file
View File

@@ -0,0 +1,157 @@
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
headless: false,
executablePath: 'C:\\Users\\xgp\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe',
args: ['--allow-file-access-from-files', '--disable-web-security'],
timeout: 120000
});
const page = await browser.newPage();
// 监听 console 日志
page.on('console', msg => {
console.log('CONSOLE:', msg.text());
});
page.on('pageerror', error => {
console.log('PAGE ERROR:', error.message);
});
await page.goto('file:///C:/Users/xgp/projects/rrweb/index.html', {
waitUntil: 'networkidle2',
timeout: 120000
});
console.log('=== 按钮绑定测试 ===\n');
// 等待 5 秒让所有脚本加载完成
await new Promise(r => setTimeout(r, 5000));
// 检查按钮绑定状态
const buttonStatus = await page.evaluate(() => {
const results = {
buttons: {},
setupCheck: {},
functionCheck: {}
};
// 检查每个按钮
const buttons = {
startBtn: document.getElementById('start-btn'),
stopBtn: document.getElementById('stop-btn'),
playToggle: document.getElementById('play-toggle-btn'),
timeline: document.getElementById('timeline')
};
for (const [key, element] of Object.entries(buttons)) {
if (element) {
results.buttons[key] = {
exists: true,
onclick: element.onclick ? 'has onclick' : 'no onclick',
onclickType: typeof element.onclick,
listeners: element._ ? Object.keys(element._.events || {}) : []
};
} else {
results.buttons[key] = { exists: false };
}
}
// 检查 setupButtons 是否被调用
const startBtn = document.getElementById('start-btn');
const playToggle = document.getElementById('play-toggle-btn');
results.setupCheck.startBtnOnclick = startBtn ? startBtn.onclick.toString() : 'null';
results.setupCheck.playToggleOnclick = playToggle ? playToggle.onclick.toString() : 'null';
// 检查函数是否存在
results.functionCheck = {
setupButtons: typeof window.setupButtons,
toggleReplay: typeof window.toggleReplay,
startRecording: typeof window.startRecording,
stopRecording: typeof window.stopRecording,
changeReplaySpeed: typeof window.changeReplaySpeed
};
// 检查速度按钮
const speedButtons = document.querySelectorAll('.speed-controls button[data-speed]');
results.setupCheck.speedButtons = Array.from(speedButtons).map(btn => ({
text: btn.textContent,
onclick: btn.onclick ? 'has onclick' : 'no onclick',
listeners: btn._ ? Object.keys(btn._.events || {}) : []
}));
return results;
});
console.log('按钮绑定状态:');
console.log(JSON.stringify(buttonStatus, null, 2));
// 如果按钮没有绑定,手动绑定它们
if (!buttonStatus.buttons.startBtn.onclick || !buttonStatus.buttons.playToggle.onclick) {
console.log('\n按钮未绑定手动绑定...');
await page.evaluate(() => {
// 确保函数存在
if (typeof window.setupButtons === 'function') {
window.setupButtons();
console.log('setupButtons() 已调用');
} else {
console.log('setupButtons() 不存在');
}
// 手动绑定关键按钮
const startBtn = document.getElementById('start-btn');
const stopBtn = document.getElementById('stop-btn');
const playToggle = document.getElementById('play-toggle-btn');
if (startBtn && !startBtn.onclick) {
startBtn.onclick = window.startRecording;
console.log('startBtn 已手动绑定');
}
if (stopBtn && !stopBtn.onclick) {
stopBtn.onclick = window.stopRecording;
console.log('stopBtn 已手动绑定');
}
if (playToggle && !playToggle.onclick) {
playToggle.onclick = window.toggleReplay;
console.log('playToggle 已手动绑定');
}
// 绑定速度按钮
const speedButtons = document.querySelectorAll('.speed-controls button[data-speed]');
speedButtons.forEach(btn => {
if (!btn.onclick) {
btn.addEventListener('click', () => {
window.changeReplaySpeed(Number(btn.dataset.speed));
});
console.log('速度按钮已绑定:', btn.textContent);
}
});
});
// 等待绑定完成
await new Promise(r => setTimeout(r, 1000));
// 重新检查状态
const recheckStatus = await page.evaluate(() => {
const startBtn = document.getElementById('start-btn');
const playToggle = document.getElementById('play-toggle-btn');
return {
startBtn: startBtn ? startBtn.onclick ? 'bound' : 'unbound' : 'not found',
playToggle: playToggle ? playToggle.onclick ? 'bound' : 'unbound' : 'not found'
};
});
console.log('\n重新检查状态:', recheckStatus);
}
await browser.close();
})().catch(e => {
console.error(e);
process.exit(1);
});