polyglot-alpha / ui /scripts /fact-check.mjs
licaomeng
deploy: main@8970ffb → HF Spaces (2026-05-27T05:19Z)
88d2f2a
import { chromium } from 'playwright';
import * as fs from 'fs';
const BASE_URL = 'http://localhost:3001';
const SCREENSHOTS_DIR = '/Users/messili/codebase/polyglot-alpha/ui/screenshots/factcheck';
async function main() {
const browser = await chromium.launch();
const results = [];
try {
// ===== PAGE 1: HOME /
console.log('Checking home page...');
const homePage = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
await homePage.goto(BASE_URL);
await homePage.waitForLoadState('networkidle');
await homePage.waitForTimeout(500);
// Claim 1: LIVE/MOCK chip
try {
const modeButtons = await homePage.locator('button').filter({ hasText: /LIVE|MOCK/ }).first();
const visible = await modeButtons.isVisible().catch(() => false);
const text = visible ? await modeButtons.textContent() : 'NOT_FOUND';
results.push({ claim: 1, status: visible ? 'TRUE' : 'FALSE', evidence: `Button: "${text}"` });
} catch (e) {
results.push({ claim: 1, status: 'FALSE', evidence: 'Selector error' });
}
// Claim 2: 5 flags
try {
const flags = await homePage.locator('img').filter({ hasText: /flag|language|lang/ }).all();
results.push({ claim: 2, status: flags.length >= 5 ? 'TRUE' : 'PARTIAL', evidence: `Found ${flags.length} flags` });
} catch {
results.push({ claim: 2, status: 'FALSE', evidence: 'No flag elements found' });
}
// Claim 3: Hero text
const heroText = await homePage.locator('main h1, main h2').first().textContent().catch(() => '');
const hasHero = heroText.toLowerCase().includes('decentralized') && heroText.toLowerCase().includes('cross-language');
results.push({ claim: 3, status: hasHero ? 'TRUE' : 'FALSE', evidence: `Text: "${heroText.substring(0, 60)}..."` });
// Claim 4: Trigger demo buttons
try {
const triggerBtn = await homePage.locator('button').filter({ hasText: /Trigger|Demo|Start/ }).first();
const visible = await triggerBtn.isVisible().catch(() => false);
const text = visible ? await triggerBtn.textContent() : 'NOT_FOUND';
results.push({ claim: 4, status: visible ? 'TRUE' : 'FALSE', evidence: `Button: "${text}"` });
} catch {
results.push({ claim: 4, status: 'FALSE', evidence: 'No trigger button found' });
}
// Claim 5: Mermaid diagram
try {
const mermaid = await homePage.locator('svg').first();
const visible = await mermaid.isVisible().catch(() => false);
results.push({ claim: 5, status: visible ? 'PARTIAL' : 'FALSE', evidence: `Diagram visible: ${visible}` });
} catch {
results.push({ claim: 5, status: 'FALSE', evidence: 'No diagram found' });
}
// Claim 6: React Flow DAG
try {
const nodes = await homePage.locator('[class*="node"]').all();
results.push({ claim: 6, status: nodes.length === 11 ? 'TRUE' : 'PARTIAL', evidence: `Found ${nodes.length} nodes (expected 11)` });
} catch {
results.push({ claim: 6, status: 'FALSE', evidence: 'No DAG found' });
}
// Claim 7: Why now / Problem section
try {
const section = await homePage.locator('h2, h3').filter({ hasText: /Why|Problem/ }).first();
const visible = await section.isVisible().catch(() => false);
results.push({ claim: 7, status: visible ? 'TRUE' : 'FALSE', evidence: `Section visible: ${visible}` });
} catch {
results.push({ claim: 7, status: 'FALSE', evidence: 'No section found' });
}
// Claim 8: Contract addresses
try {
const contracts = await homePage.locator('span, code').filter({ hasText: /0x[a-f0-9]/ }).all();
results.push({ claim: 8, status: contracts.length >= 5 ? 'TRUE' : 'PARTIAL', evidence: `Found ${contracts.length} contracts` });
} catch {
results.push({ claim: 8, status: 'FALSE', evidence: 'No contracts found' });
}
await homePage.screenshot({ path: `${SCREENSHOTS_DIR}/home.png` });
await homePage.close();
// ===== PAGE 2: /ABOUT
console.log('Checking about page...');
const aboutPage = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
await aboutPage.goto(`${BASE_URL}/about`);
await aboutPage.waitForLoadState('networkidle');
// Claim 9: 5-phase pipeline
try {
const text = await aboutPage.locator('main').textContent();
const phases = (text.match(/phase/gi) || []).length;
results.push({ claim: 9, status: phases >= 5 ? 'TRUE' : 'FALSE', evidence: `Found ${phases} phase mentions` });
} catch {
results.push({ claim: 9, status: 'FALSE', evidence: 'Error reading text' });
}
// Claim 10: How it works section
try {
const section = await aboutPage.locator('h2, h3').filter({ hasText: /How/ }).first();
const visible = await section.isVisible().catch(() => false);
const text = visible ? await section.textContent() : 'NOT_FOUND';
results.push({ claim: 10, status: visible ? 'TRUE' : 'FALSE', evidence: `Section: "${text}"` });
} catch {
results.push({ claim: 10, status: 'FALSE', evidence: 'No section found' });
}
// Claim 11: Glossary
try {
const items = await aboutPage.locator('[class*="glossary"], [class*="component"], dl dt, li').all();
results.push({ claim: 11, status: items.length >= 11 ? 'TRUE' : 'PARTIAL', evidence: `Found ${items.length} items` });
} catch {
results.push({ claim: 11, status: 'FALSE', evidence: 'No glossary found' });
}
await aboutPage.screenshot({ path: `${SCREENSHOTS_DIR}/about.png` });
await aboutPage.close();
// ===== PAGE 3: /OPERATORS
console.log('Checking operators page...');
const operatorsPage = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
await operatorsPage.goto(`${BASE_URL}/operators`);
await operatorsPage.waitForLoadState('networkidle');
// Claim 12: 3 seeder cards
try {
const cards = await operatorsPage.locator('[class*="card"], div[role="article"]').all();
results.push({ claim: 12, status: cards.length >= 3 ? 'TRUE' : 'PARTIAL', evidence: `Found ${cards.length} cards` });
} catch {
results.push({ claim: 12, status: 'FALSE', evidence: 'No cards found' });
}
// Claim 13: wins/bids 26%
try {
const winsBids = await operatorsPage.locator('text=/wins|bids/i').first();
const visible = await winsBids.isVisible().catch(() => false);
results.push({ claim: 13, status: visible ? 'TRUE' : 'FALSE', evidence: `Visible: ${visible}` });
} catch {
results.push({ claim: 13, status: 'FALSE', evidence: 'No wins/bids found' });
}
// Claim 14: EMA dashed border
try {
const ema = await operatorsPage.locator('text=/EMA/').first();
const visible = await ema.isVisible().catch(() => false);
results.push({ claim: 14, status: visible ? 'PARTIAL' : 'FALSE', evidence: `EMA visible: ${visible}` });
} catch {
results.push({ claim: 14, status: 'FALSE', evidence: 'No EMA found' });
}
// Claim 15: Buttons
try {
const allBtns = await operatorsPage.locator('button').all();
const btnTexts = await Promise.all(allBtns.slice(0, 20).map(b => b.textContent().catch(() => '')));
const hasAll = btnTexts.join('').includes('Claim') && btnTexts.join('').includes('Withdraw') && btnTexts.join('').includes('Register');
results.push({ claim: 15, status: hasAll ? 'TRUE' : 'PARTIAL', evidence: `Button count: ${allBtns.length}` });
} catch {
results.push({ claim: 15, status: 'FALSE', evidence: 'Error checking buttons' });
}
await operatorsPage.screenshot({ path: `${SCREENSHOTS_DIR}/operators.png` });
await operatorsPage.close();
// ===== PAGE 4: EVENT DETAIL
console.log('Checking event detail...');
const eventsPage = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
await eventsPage.goto(`${BASE_URL}/events`);
await eventsPage.waitForLoadState('networkidle');
// Try to find event
const eventLink = await eventsPage.locator('a').filter({ hasText: /[0-9]/ }).first();
let eventUrl = null;
try {
eventUrl = await eventLink.getAttribute('href');
} catch {}
if (eventUrl) {
const fullUrl = eventUrl.startsWith('/') ? BASE_URL + eventUrl : BASE_URL + '/' + eventUrl;
console.log(`Opening event: ${fullUrl}`);
const eventPage = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
await eventPage.goto(fullUrl);
await eventPage.waitForLoadState('networkidle');
await eventPage.waitForTimeout(1000);
// Claim 16: Judge dossier
try {
const judges = await eventPage.locator('tr, [class*="judge"]').all();
const count = judges.length;
results.push({ claim: 16, status: count >= 11 ? 'TRUE' : 'PARTIAL', evidence: `Found ${count} judge rows` });
} catch {
results.push({ claim: 16, status: 'FALSE', evidence: 'No judges found' });
}
// Claim 17: Attestation tx
try {
const tx = await eventPage.locator('span, code').filter({ hasText: /0xsim/ }).first();
const visible = await tx.isVisible().catch(() => false);
results.push({ claim: 17, status: visible ? 'PARTIAL' : 'FALSE', evidence: `Tx visible: ${visible}` });
} catch {
results.push({ claim: 17, status: 'FALSE', evidence: 'No tx found' });
}
// Claim 18: Dossier button
try {
const btn = await eventPage.locator('button').filter({ hasText: /dossier|raw|JSON/i }).first();
const visible = await btn.isVisible().catch(() => false);
results.push({ claim: 18, status: visible ? 'TRUE' : 'FALSE', evidence: `Button visible: ${visible}` });
} catch {
results.push({ claim: 18, status: 'FALSE', evidence: 'No button found' });
}
// Claim 19: IPFS link
try {
const ipfs = await eventPage.locator('text=/ipfs:/i').first();
const visible = await ipfs.isVisible().catch(() => false);
results.push({ claim: 19, status: visible ? 'PARTIAL' : 'FALSE', evidence: `IPFS visible: ${visible}` });
} catch {
results.push({ claim: 19, status: 'FALSE', evidence: 'No IPFS found' });
}
// Claim 20: API payload button
try {
const btn = await eventPage.locator('button').filter({ hasText: /API|Payload/ }).first();
const visible = await btn.isVisible().catch(() => false);
results.push({ claim: 20, status: visible ? 'TRUE' : 'FALSE', evidence: `Button visible: ${visible}` });
} catch {
results.push({ claim: 20, status: 'FALSE', evidence: 'No button found' });
}
// Claim 21: Fee split
try {
const fees = await eventPage.locator('[class*="fee"], tr').all();
results.push({ claim: 21, status: fees.length >= 2 ? 'TRUE' : 'PARTIAL', evidence: `Found ${fees.length} fee items` });
} catch {
results.push({ claim: 21, status: 'FALSE', evidence: 'No fees found' });
}
// Claim 22: Debate panel
try {
const panel = await eventPage.locator('[class*="debate"], [class*="agent"]').first();
const visible = await panel.isVisible().catch(() => false);
results.push({ claim: 22, status: visible ? 'PARTIAL' : 'FALSE', evidence: `Panel visible: ${visible}` });
} catch {
results.push({ claim: 22, status: 'FALSE', evidence: 'No debate panel found' });
}
const filename = eventUrl.split('/').pop();
await eventPage.screenshot({ path: `${SCREENSHOTS_DIR}/event-${filename}.png` });
await eventPage.close();
}
await eventsPage.close();
} catch (error) {
console.error('Script error:', error.message);
} finally {
await browser.close();
}
// Output results
console.log('\n===== FACT-CHECK RESULTS =====\n');
results.forEach((r) => {
console.log(`${r.claim}. Status: ${r.status} | ${r.evidence}`);
});
fs.writeFileSync(`${SCREENSHOTS_DIR}/factcheck-results.json`, JSON.stringify(results, null, 2));
console.log(`\nResults saved.`);
}
main().catch(console.error);