1
0
Fork 0
mirror of https://github.com/imjasonh/apkviz synced 2026-07-16 20:35:50 +00:00
apkviz/test-stats.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

45 lines
No EOL
1.4 KiB
JavaScript

const { chromium } = require('playwright');
// Ensure output directory exists
const fs = require('fs');
if (!fs.existsSync('playwright-output')) {
fs.mkdirSync('playwright-output', { recursive: true });
}
async function testStats() {
const browser = await chromium.launch({ headless: false, slowMo: 100 });
const page = await browser.newPage();
await page.goto('http://localhost:8081', { waitUntil: 'networkidle' });
await page.waitForTimeout(2000);
// Search for different packages to see their stats
const testPackages = ['glibc', 'gcc', 'python', 'nodejs'];
for (const pkg of testPackages) {
console.log(`\nTesting ${pkg}...`);
// Clear search and type new package
await page.fill('#search', '');
await page.type('#search', pkg, { delay: 50 });
await page.waitForTimeout(2000);
// Check if stats are visible
const statsVisible = await page.$('#package-stats');
if (statsVisible) {
const statsContent = await page.$eval('#package-stats', el => el.textContent);
console.log('Stats found:', statsContent.substring(0, 100) + '...');
// Take screenshot
await page.screenshot({ path: `stats-${pkg}.png`, fullPage: true });
} else {
console.log('No stats panel found');
}
}
console.log('\nKeeping browser open for manual inspection...');
// Keep browser open
await new Promise(() => {});
}
testStats().catch(console.error);