1
0
Fork 0
mirror of https://github.com/imjasonh/apkviz synced 2026-07-08 01:45:15 +00:00
apkviz/test-glibc.js
Jason Hall c9fe336400
Add Wolfi APK dependency visualizer with advanced analytics
This web application visualizes package dependencies in the Wolfi Linux distribution,
providing powerful insights into the package ecosystem.

Features:
- Interactive force-directed dependency graph visualization
- Shows both forward dependencies (what a package depends on) and reverse dependencies (what depends on it)
- Click any node to re-center the visualization on that package
- Transitive dependency analysis with toggle control
- Advanced package analytics including:
  - Criticality scores showing how many packages depend on each package
  - Total size impact analysis (package + all dependencies)
  - Dependency depth metrics
  - Bus factor warnings for critical infrastructure packages
- "Most Critical Packages" dashboard showing system-wide statistics
- Real-time search with auto-complete
- Different visual styles for direct vs transitive dependencies
- Playwright-based testing infrastructure for automated UI testing

Technical implementation:
- TypeScript + D3.js for visualization
- Webpack build system
- Analyzes Wolfi's APKINDEX for package metadata
- Efficient dependency graph algorithms
- Responsive design with detailed package information panel

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-13 15:41:49 -04:00

48 lines
No EOL
1.5 KiB
JavaScript

const { chromium } = require('playwright');
async function testGlibc() {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// Capture console logs
const logs = [];
page.on('console', msg => logs.push(`[${msg.type()}] ${msg.text()}`));
page.on('pageerror', err => logs.push(`[ERROR] ${err.message}`));
await page.goto('http://localhost:8081', { waitUntil: 'networkidle' });
await page.waitForTimeout(2000);
// Search for glibc
await page.type('#search', 'glibc');
await page.waitForTimeout(3000);
// Take screenshot
await page.screenshot({ path: 'playwright-output/glibc-deps.png', fullPage: true });
console.log('Screenshot saved to glibc-deps.png');
// Get visualization state
const vizState = await page.evaluate(() => {
const circles = document.querySelectorAll('circle');
const lines = document.querySelectorAll('line');
return {
nodeCount: circles.length,
linkCount: lines.length,
linkTypes: Array.from(lines).map(l => l.getAttribute('class')).filter((v, i, a) => a.indexOf(v) === i)
};
});
console.log('\nVisualization state:');
console.log(`Nodes: ${vizState.nodeCount}, Links: ${vizState.linkCount}`);
console.log('Link types:', vizState.linkTypes);
// Check for errors
const errors = logs.filter(log => log.includes('ERROR') || log.includes('error'));
if (errors.length > 0) {
console.log('\nErrors found:');
errors.forEach(err => console.log(err));
}
await browser.close();
}
testGlibc().catch(console.error);