187 lines
6.8 KiB
JavaScript
187 lines
6.8 KiB
JavaScript
import { chromium } from 'playwright';
|
|
import { readFileSync } from 'fs';
|
|
|
|
const BROWSER = await chromium.launch({ headless: true });
|
|
const PAGE = await BROWSER.newPage();
|
|
const logs = [];
|
|
PAGE.on('console', msg => logs.push(`[${msg.type()}] ${msg.text()}`));
|
|
PAGE.on('pageerror', err => logs.push(`[PAGE_ERROR] ${err.message}`));
|
|
|
|
const BASE = 'http://localhost:5174/pindou/';
|
|
|
|
// ===== STEP 1: Load index page, inject test image into store =====
|
|
console.log('=== STEP 1: Load index page ===');
|
|
await PAGE.goto(`${BASE}#/`, { waitUntil: 'networkidle', timeout: 15000 });
|
|
await PAGE.waitForTimeout(1500);
|
|
|
|
// Create a simple test image data URL (a small colored PNG)
|
|
// Use page.evaluate to create a canvas, draw something, and get data URL
|
|
const imageDataUrl = await PAGE.evaluate(() => {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 100;
|
|
canvas.height = 100;
|
|
const ctx = canvas.getContext('2d');
|
|
// Draw a gradient
|
|
const gradient = ctx.createLinearGradient(0, 0, 100, 100);
|
|
gradient.addColorStop(0, '#ff0000');
|
|
gradient.addColorStop(0.25, '#00ff00');
|
|
gradient.addColorStop(0.5, '#0000ff');
|
|
gradient.addColorStop(0.75, '#ffff00');
|
|
gradient.addColorStop(1, '#ff00ff');
|
|
ctx.fillStyle = gradient;
|
|
ctx.fillRect(0, 0, 100, 100);
|
|
return canvas.toDataURL('image/png');
|
|
});
|
|
console.log('Test image created:', imageDataUrl.substring(0, 50) + '...');
|
|
|
|
// Inject image into store via sessionStorage
|
|
await PAGE.evaluate((img) => {
|
|
sessionStorage.setItem('bead-process-state', JSON.stringify({
|
|
sourceImage: img,
|
|
extractedImage: null,
|
|
canvasWidth: 29,
|
|
canvasHeight: 29,
|
|
fitMode: 'fit',
|
|
grid: [],
|
|
legend: [],
|
|
totalBeads: 0,
|
|
usedColors: 0,
|
|
status: 'idle',
|
|
}));
|
|
}, imageDataUrl);
|
|
|
|
// Navigate to editor page
|
|
console.log('\n=== STEP 2: Navigate to editor ===');
|
|
await PAGE.goto(`${BASE}#/pages/editor/editor`, { waitUntil: 'networkidle', timeout: 15000 });
|
|
await PAGE.waitForTimeout(1500);
|
|
|
|
// Check editor state
|
|
const editorState = await PAGE.evaluate(() => {
|
|
const buttons = Array.from(document.querySelectorAll('uni-button, button, [class*="btn"]'))
|
|
.map(b => ({ text: b.textContent?.trim(), visible: b.offsetParent !== null }));
|
|
const inputs = Array.from(document.querySelectorAll('input, uni-input'))
|
|
.map(i => ({ type: i.type, value: i.value, placeholder: i.placeholder }));
|
|
return { buttons, inputs };
|
|
});
|
|
console.log('Editor state:', JSON.stringify(editorState, null, 2));
|
|
|
|
// Try to find and click the "生成图纸" button
|
|
const genBtn = await PAGE.evaluate(() => {
|
|
const all = Array.from(document.querySelectorAll('uni-button, button, uni-view, uni-text, view, text'));
|
|
const btn = all.find(el => el.textContent?.includes('生成图纸'));
|
|
return btn ? { found: true, tag: btn.tagName, text: btn.textContent?.trim() } : { found: false };
|
|
});
|
|
console.log('Generate button:', JSON.stringify(genBtn));
|
|
|
|
if (genBtn.found) {
|
|
// Click the generate button
|
|
const clicked = await PAGE.evaluate(() => {
|
|
const all = Array.from(document.querySelectorAll('uni-button, button, uni-view, uni-text, view, text'));
|
|
const btn = all.find(el => el.textContent?.includes('生成图纸'));
|
|
if (btn) {
|
|
btn.click();
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
console.log('Clicked generate button:', clicked);
|
|
await PAGE.waitForTimeout(500);
|
|
}
|
|
|
|
// Check if we navigated
|
|
const currentHash = await PAGE.evaluate(() => window.location.hash);
|
|
console.log('Current hash after click:', currentHash);
|
|
|
|
// If not navigated, manually go to processing
|
|
if (!currentHash.includes('processing')) {
|
|
console.log('\n=== STEP 3: Manually navigate to processing ===');
|
|
await PAGE.goto(`${BASE}#/pages/processing/processing`, { waitUntil: 'networkidle', timeout: 15000 });
|
|
await PAGE.waitForTimeout(2000);
|
|
}
|
|
|
|
// Check processing page
|
|
const procState = await PAGE.evaluate(() => {
|
|
const progressEl = document.querySelector('[class*="progress"]');
|
|
const statusEl = document.querySelector('[class*="status"]');
|
|
const allText = document.body?.textContent?.substring(0, 500);
|
|
return {
|
|
hash: window.location.hash,
|
|
progressText: progressEl?.textContent?.trim(),
|
|
statusText: statusEl?.textContent?.trim(),
|
|
bodyText: allText,
|
|
};
|
|
});
|
|
console.log('Processing state:', JSON.stringify(procState, null, 2));
|
|
|
|
// Wait for processing to complete (up to 10 seconds)
|
|
let done = false;
|
|
for (let i = 0; i < 10; i++) {
|
|
await PAGE.waitForTimeout(1000);
|
|
const hash = await PAGE.evaluate(() => window.location.hash);
|
|
if (hash.includes('result')) {
|
|
console.log('Navigated to result page!');
|
|
done = true;
|
|
break;
|
|
}
|
|
const procStatus = await PAGE.evaluate(() => document.body?.textContent?.substring(0, 200));
|
|
console.log(` Wait ${i+1}s: hash=${hash}, body=${procStatus}`);
|
|
}
|
|
|
|
if (!done) {
|
|
console.log('Processing did not auto-navigate. Checking sessionStorage...');
|
|
const ssData = await PAGE.evaluate(() => {
|
|
const raw = sessionStorage.getItem('bead-process-state');
|
|
if (!raw) return null;
|
|
const d = JSON.parse(raw);
|
|
return { gridLength: d.grid?.length, totalBeads: d.totalBeads, status: d.status };
|
|
});
|
|
console.log('sessionStorage state:', JSON.stringify(ssData));
|
|
|
|
// Force navigate to result
|
|
await PAGE.goto(`${BASE}#/pages/result/result`, { waitUntil: 'networkidle', timeout: 15000 });
|
|
await PAGE.waitForTimeout(2000);
|
|
}
|
|
|
|
// ===== STEP 4: Check result page =====
|
|
console.log('\n=== STEP 4: Result page ===');
|
|
const resultState = await PAGE.evaluate(() => {
|
|
const canvasInner = document.querySelector('.canvas-inner');
|
|
const allCanvases = Array.from(document.querySelectorAll('canvas'));
|
|
const emptyState = document.querySelector('.empty-state');
|
|
const infoBar = document.querySelector('.info-bar');
|
|
|
|
return {
|
|
hash: window.location.hash,
|
|
emptyStateVisible: !!emptyState && emptyState.offsetParent !== null,
|
|
emptyStateText: emptyState?.textContent?.trim(),
|
|
infoBarText: infoBar?.textContent?.trim(),
|
|
canvasInnerHTML: canvasInner?.innerHTML?.substring(0, 300),
|
|
canvasInnerChildCount: canvasInner?.children?.length,
|
|
canvasCount: allCanvases.length,
|
|
canvases: allCanvases.map(c => ({ w: c.width, h: c.height })),
|
|
};
|
|
});
|
|
console.log(JSON.stringify(resultState, null, 2));
|
|
|
|
// Print relevant logs
|
|
console.log('\n=== Relevant Logs ===');
|
|
logs.filter(l =>
|
|
l.includes('BeadPattern') ||
|
|
l.includes('result.vue') ||
|
|
l.includes('processStore') ||
|
|
l.includes('pipeline') ||
|
|
l.includes('PAGE_ERROR') ||
|
|
l.includes('Processing') ||
|
|
l.includes('renderCanvas') ||
|
|
l.includes('setResult') ||
|
|
l.includes('saveToStorage') ||
|
|
l.includes('Restored') ||
|
|
l.includes('hasValidData') ||
|
|
l.includes('Grid watch')
|
|
).forEach(l => console.log(l));
|
|
|
|
await PAGE.screenshot({ path: '/Users/guchen/.openclaw/workspace/pindou-flow-debug.png', fullPage: true });
|
|
console.log('\nScreenshot saved to pindou-flow-debug.png');
|
|
|
|
await BROWSER.close();
|