init repo
This commit is contained in:
174
debug-export.mjs
Normal file
174
debug-export.mjs
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* 调试导出:点击导出按钮后,监控网络请求、页面变化、弹窗等
|
||||
*/
|
||||
import { chromium } from 'playwright';
|
||||
import { readFileSync, existsSync, mkdirSync } from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const COOKIE_FILE = path.join(__dirname, 'cookies.json');
|
||||
const SS = path.join(__dirname, 'screenshots');
|
||||
const BASE = 'https://www.dianxiaomi.com';
|
||||
|
||||
mkdirSync(SS, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({
|
||||
viewport: { width: 1920, height: 1080 }, locale: 'zh-CN',
|
||||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||
acceptDownloads: true,
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Cookie
|
||||
await ctx.addCookies(JSON.parse(readFileSync(COOKIE_FILE, 'utf-8')));
|
||||
|
||||
// 监听所有网络请求
|
||||
page.on('request', req => {
|
||||
const url = req.url();
|
||||
if (url.includes('export') || url.includes('Export') || url.includes('download') ||
|
||||
url.includes('Download') || url.includes('导出') || url.includes('.xls') ||
|
||||
url.includes('.csv') || url.includes('.xlsx')) {
|
||||
console.log(` [REQ] ${req.method()} ${url}`);
|
||||
if (req.postData()) console.log(` [POST] ${req.postData().substring(0, 200)}`);
|
||||
}
|
||||
});
|
||||
|
||||
page.on('response', async resp => {
|
||||
const url = resp.url();
|
||||
if (url.includes('export') || url.includes('Export') || url.includes('download') ||
|
||||
url.includes('Download') || url.includes('.xls') || url.includes('.csv')) {
|
||||
const ct = resp.headers()['content-type'] || '';
|
||||
const cd = resp.headers()['content-disposition'] || '';
|
||||
console.log(` [RESP] ${resp.status()} ${url.substring(0, 100)}`);
|
||||
console.log(` [CT] ${ct} [CD] ${cd}`);
|
||||
if (ct.includes('json') || ct.includes('text')) {
|
||||
try {
|
||||
const body = await resp.text();
|
||||
console.log(` [BODY] ${body.substring(0, 500)}`);
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
page.on('download', d => {
|
||||
console.log(` [DOWNLOAD] ${d.suggestedFilename()} url=${d.url()}`);
|
||||
});
|
||||
|
||||
page.on('dialog', async d => {
|
||||
console.log(` [DIALOG] ${d.type()}: ${d.message()}`);
|
||||
await d.accept();
|
||||
});
|
||||
|
||||
// 监听新页面/标签
|
||||
ctx.on('page', p => {
|
||||
console.log(` [NEW PAGE] ${p.url()}`);
|
||||
});
|
||||
|
||||
// === 测试采购建议的导出 ===
|
||||
console.log('\n=== 采购建议页面 ===');
|
||||
await page.goto(`${BASE}/purchasingProposal/index.htm?state=3`, { waitUntil: 'load', timeout: 30000 });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 点击"导出建议"下拉
|
||||
const dropdown = await page.locator('text=导出建议').first();
|
||||
await dropdown.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 点击"导出全部"
|
||||
console.log('>> 点击"导出全部"...');
|
||||
const exportAll = await page.locator('text=导出全部').first();
|
||||
await exportAll.click();
|
||||
|
||||
// 等待并观察
|
||||
console.log('>> 等待 15 秒观察反应...');
|
||||
await page.waitForTimeout(15000);
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: path.join(SS, 'debug-after-export-click.png'), fullPage: true });
|
||||
|
||||
// 检查页面变化
|
||||
const alerts = await page.evaluate(() => {
|
||||
// 检查是否有弹窗/提示
|
||||
const modals = document.querySelectorAll('.el-dialog, .modal, [class*="dialog"], [class*="modal"], [class*="popup"], [class*="toast"], [class*="message"], [class*="notify"]');
|
||||
return Array.from(modals).map(m => ({
|
||||
visible: m.offsetHeight > 0,
|
||||
text: m.textContent?.substring(0, 200),
|
||||
cls: m.className?.substring(0, 80),
|
||||
})).filter(m => m.visible);
|
||||
});
|
||||
|
||||
if (alerts.length) {
|
||||
console.log('\n>> 弹窗/提示:');
|
||||
alerts.forEach(a => console.log(` ${a.cls}: "${a.text}"`));
|
||||
}
|
||||
|
||||
// 检查是否有 iframe
|
||||
const iframes = await page.$$('iframe');
|
||||
console.log(`\n>> iframe 数量: ${iframes.length}`);
|
||||
|
||||
// 查看页面当前状态
|
||||
const pageText = await page.evaluate(() => document.body?.innerText?.substring(0, 3000));
|
||||
console.log('\n>> 页面当前文本(前1500字):\n', pageText?.substring(0, 1500));
|
||||
|
||||
await page.screenshot({ path: path.join(SS, 'debug-final.png') });
|
||||
|
||||
// === 同样测试仓库 ===
|
||||
console.log('\n\n=== 仓库页面 ===');
|
||||
await page.goto(`${BASE}/warehouseProduct/index.htm`, { waitUntil: 'load', timeout: 30000 });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 导入/导出 → 按所有页导出
|
||||
const impExpBtn = await page.locator('text=导入/导出').first();
|
||||
await impExpBtn.click();
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
console.log('>> 点击"按所有页导出"...');
|
||||
const allPages = await page.locator('text=按所有页导出').first();
|
||||
await allPages.click();
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 看看弹窗
|
||||
await page.screenshot({ path: path.join(SS, 'debug-warehouse-dialog.png') });
|
||||
|
||||
// 找到并点击对话框的导出按钮
|
||||
console.log('>> 查找对话框中的导出按钮...');
|
||||
const dialogBtns = await page.$$eval('button', els =>
|
||||
els.filter(el => el.offsetHeight > 0)
|
||||
.map(el => ({
|
||||
text: el.textContent.trim(), id: el.id,
|
||||
cls: (el.className || '').substring(0, 60),
|
||||
rect: el.getBoundingClientRect(),
|
||||
})).filter(e => e.text.includes('导出') || e.text.includes('确认') || e.text.includes('确定'))
|
||||
);
|
||||
console.log(' 可见导出/确认按钮:', JSON.stringify(dialogBtns, null, 2));
|
||||
|
||||
if (dialogBtns.length) {
|
||||
// 点击最后一个"导出"按钮(通常是对话框内的)
|
||||
const targetText = dialogBtns.find(b => b.text === '导出')?.text || dialogBtns[0].text;
|
||||
console.log(`>> 点击按钮: "${targetText}"`);
|
||||
const btn = await page.locator(`button:visible:has-text("${targetText}")`).last();
|
||||
await btn.click();
|
||||
|
||||
console.log('>> 等待 15 秒...');
|
||||
await page.waitForTimeout(15000);
|
||||
|
||||
await page.screenshot({ path: path.join(SS, 'debug-warehouse-after-confirm.png') });
|
||||
|
||||
// 再次检查弹窗
|
||||
const alerts2 = await page.evaluate(() => {
|
||||
const modals = document.querySelectorAll('.el-dialog, .modal, [class*="dialog"], [class*="message"], [class*="notify"], [class*="toast"]');
|
||||
return Array.from(modals).map(m => ({
|
||||
visible: m.offsetHeight > 0,
|
||||
text: m.textContent?.substring(0, 300),
|
||||
})).filter(m => m.visible);
|
||||
});
|
||||
if (alerts2.length) {
|
||||
console.log('\n>> 点击后弹窗:');
|
||||
alerts2.forEach(a => console.log(` "${a.text}"`));
|
||||
}
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
console.log('\n>> 完成');
|
||||
Reference in New Issue
Block a user