Merge develop into test - sync latest code
This commit is contained in:
153
zentao_bug_fetch.js
Normal file
153
zentao_bug_fetch.js
Normal file
@@ -0,0 +1,153 @@
|
||||
const { chromium } = require('playwright');
|
||||
const fs = require('fs');
|
||||
|
||||
async function fetchBug(bugId) {
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
||||
});
|
||||
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1920, height: 2000 }
|
||||
});
|
||||
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
const zentaoUrl = 'https://zentao.gentronhealth.com';
|
||||
|
||||
// Step 1: 访问登录页面
|
||||
console.log('[Step 1] 访问登录页面...');
|
||||
await page.goto(zentaoUrl + '/user-login.html', {
|
||||
waitUntil: 'networkidle',
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
// Step 2: 登录
|
||||
console.log('[Step 2] 登录...');
|
||||
await page.waitForSelector('#account', { timeout: 10000 });
|
||||
await page.fill('#account', 'admin');
|
||||
await page.fill('input[name="password"]', 'Jchl1528');
|
||||
|
||||
await Promise.all([
|
||||
page.click('#submit'),
|
||||
page.waitForNavigation({ waitUntil: 'networkidle', timeout: 60000 })
|
||||
]);
|
||||
|
||||
console.log('[Step 3] 登录成功');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Step 4: 访问BUG详情页面
|
||||
console.log(`[Step 4] 访问 BUG #${bugId} ...`);
|
||||
const bugUrl = zentaoUrl + '/index.php?m=bug&f=view&bugID=' + bugId;
|
||||
await page.goto(bugUrl, {
|
||||
waitUntil: 'networkidle',
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Step 5: 关键!使用frameLocator获取iframe内容
|
||||
console.log('[Step 5] 获取iframe内容...');
|
||||
|
||||
const frame = page.frameLocator('iframe[name="app-qa"]');
|
||||
const bodyElement = frame.locator('body');
|
||||
|
||||
// 等待iframe内容加载
|
||||
await bodyElement.waitFor({ state: 'visible', timeout: 10000 }).catch(() => {});
|
||||
|
||||
// Step 6: 提取BUG信息
|
||||
const bugData = await bodyElement.evaluate(() => {
|
||||
const info = {
|
||||
title: '',
|
||||
description: '',
|
||||
steps: '',
|
||||
expected: '',
|
||||
actual: '',
|
||||
priority: '',
|
||||
status: '',
|
||||
module: '',
|
||||
assignedTo: '',
|
||||
openedBy: '',
|
||||
bugType: '',
|
||||
severity: '',
|
||||
allText: document.body.innerText
|
||||
};
|
||||
|
||||
// 获取标题
|
||||
const titleEl = document.querySelector('.page-title, h1, h2, .title');
|
||||
if (titleEl) {
|
||||
info.title = titleEl.textContent.replace(/^\d+\s*/, '').trim();
|
||||
}
|
||||
|
||||
// 获取表格数据
|
||||
const rows = document.querySelectorAll('table.table-form tr');
|
||||
rows.forEach(row => {
|
||||
const th = row.querySelector('th');
|
||||
const td = row.querySelector('td');
|
||||
if (th && td) {
|
||||
const label = th.textContent.trim();
|
||||
const value = td.textContent.trim();
|
||||
|
||||
if (label.includes('所属模块')) info.module = value;
|
||||
else if (label.includes('优先级')) info.priority = value;
|
||||
else if (label.includes('Bug状态') || label.includes('状态')) info.status = value;
|
||||
else if (label.includes('指派给')) info.assignedTo = value;
|
||||
else if (label.includes('创建')) info.openedBy = value;
|
||||
else if (label.includes('Bug类型')) info.bugType = value;
|
||||
else if (label.includes('严重程度')) info.severity = value;
|
||||
}
|
||||
});
|
||||
|
||||
return info;
|
||||
});
|
||||
|
||||
// 从完整文本提取描述和步骤
|
||||
const fullText = bugData.allText;
|
||||
|
||||
const descMatch = fullText.match(/\[步骤\]([\s\S]*?)\[结果\]/);
|
||||
if (descMatch) bugData.steps = descMatch[1].trim();
|
||||
|
||||
const actualMatch = fullText.match(/\[结果\]([\s\S]*?)\[期望\]/);
|
||||
if (actualMatch) bugData.actual = actualMatch[1].trim();
|
||||
|
||||
const expectedMatch = fullText.match(/\[期望\]([\s\S]*?)(?=历史记录|$)/);
|
||||
if (expectedMatch) bugData.expected = expectedMatch[1].trim();
|
||||
|
||||
// 输出结果
|
||||
console.log('\n==== BUG #' + bugId + ' 详细信息 ====');
|
||||
console.log(JSON.stringify(bugData, null, 2));
|
||||
|
||||
// 保存到文件
|
||||
fs.writeFileSync(`zentao_bug_${bugId}_parsed.json`, JSON.stringify(bugData, null, 2));
|
||||
|
||||
// 保存截图
|
||||
await page.screenshot({ path: `zentao_bug_${bugId}.png`, fullPage: true });
|
||||
|
||||
return { success: true, data: bugData };
|
||||
|
||||
} catch (error) {
|
||||
console.error('[Error]', error.message);
|
||||
await page.screenshot({ path: `zentao_bug_${bugId}_error.png`, fullPage: true });
|
||||
return { success: false, error: error.message };
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
const bugId = 320;
|
||||
|
||||
console.log(`开始获取禅道 BUG #${bugId}...`);
|
||||
const result = await fetchBug(bugId);
|
||||
|
||||
if (!result.success) {
|
||||
console.log('\n❌ 获取失败!');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('\n✅ 获取成功!');
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user